Download multiple files from Ftp issue
-
Hi! I want to download some files from my ftp server. The problem is, that only the last one has data, others 0 sized or it crashes when close
QFileas a pointer.My code:
QFtp *ftp = new QFtp(this); ftp->connectToHost(FTP_HOST, FTP_PORT); ftp->login(FTP_USERNAME, FTP_PASSWORD); QFile *reportFile = nullptr; connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) { if (ftpUrlInfo.isFile()) { reportFile = new QFile("some local path" + ftpUrlInfo.name()); reportFile->open(QIODevice::WriteOnly); ftp->get("some ftp path" + ftpUrlInfo.name(), reportFile, QFtp::Binary); } }); connect(ftp, &QFtp::done, [this]() { qDebug() << "DONE!"; ftp->close(); ftp->deleteLater(); }); connect(ftp, &QFtp::commandFinished, [this]() { qDebug() << "COMMAND FINISHED!"; if (reportFile != nullptr) { reportFile.close(); reportFile->deleteLater(); } }); ftp->list("ftp path to dir");So, it should download the file, close it and
deleteLaterfor all files in the ftp directory. Any ideas how to do it? Thanks. -
Hi! I want to download some files from my ftp server. The problem is, that only the last one has data, others 0 sized or it crashes when close
QFileas a pointer.My code:
QFtp *ftp = new QFtp(this); ftp->connectToHost(FTP_HOST, FTP_PORT); ftp->login(FTP_USERNAME, FTP_PASSWORD); QFile *reportFile = nullptr; connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) { if (ftpUrlInfo.isFile()) { reportFile = new QFile("some local path" + ftpUrlInfo.name()); reportFile->open(QIODevice::WriteOnly); ftp->get("some ftp path" + ftpUrlInfo.name(), reportFile, QFtp::Binary); } }); connect(ftp, &QFtp::done, [this]() { qDebug() << "DONE!"; ftp->close(); ftp->deleteLater(); }); connect(ftp, &QFtp::commandFinished, [this]() { qDebug() << "COMMAND FINISHED!"; if (reportFile != nullptr) { reportFile.close(); reportFile->deleteLater(); } }); ftp->list("ftp path to dir");So, it should download the file, close it and
deleteLaterfor all files in the ftp directory. Any ideas how to do it? Thanks.@Cobra91151
How are you waiting for one file'sget()to finish, before you set off the next one? You are reusing the samereportFilevariable over & over, while it is still servicing previous fileget()s? Hence you only get the final file, and the crashes when one file'sreportFile.close();closes/deletes thereportFilefrom a different file!? (Put aqDebug()in the firstconnect(), not just the other two.)Either wait if you want to do one-at-a-time synchronously, or you need to maintain multiple different
reportFiles to do them all asynchronously. -
@Cobra91151
How are you waiting for one file'sget()to finish, before you set off the next one? You are reusing the samereportFilevariable over & over, while it is still servicing previous fileget()s? Hence you only get the final file, and the crashes when one file'sreportFile.close();closes/deletes thereportFilefrom a different file!? (Put aqDebug()in the firstconnect(), not just the other two.)Either wait if you want to do one-at-a-time synchronously, or you need to maintain multiple different
reportFiles to do them all asynchronously.Ok. I will change code and reply. Thanks.
-
I have tried to use
QList<QFile*>and append the files when they are listing, and then loop it, and when commandget()finished, close anddeleteLater()the file, now it doesn't crash when useQFileas a pointer but all files are 0 sized.if (ftp->currentCommand() == QFtp::Get) { qDebug() << "GET FINISHED!"; reportFile->close(); reportFile->deleteLater(); }I think that here is better to use
QQueueand proceed the file one by one. -
I have tried to use
QList<QFile*>and append the files when they are listing, and then loop it, and when commandget()finished, close anddeleteLater()the file, now it doesn't crash when useQFileas a pointer but all files are 0 sized.if (ftp->currentCommand() == QFtp::Get) { qDebug() << "GET FINISHED!"; reportFile->close(); reportFile->deleteLater(); }I think that here is better to use
QQueueand proceed the file one by one.Hi
Did you replace reportFile with access to the QList<QFile*>
so each invocation works on the right QFile?
Should work just as fine as one.
But yeah if 1 download works, than using a queue should be ok easy. -
Hi
Did you replace reportFile with access to the QList<QFile*>
so each invocation works on the right QFile?
Should work just as fine as one.
But yeah if 1 download works, than using a queue should be ok easy.Yes, 1 file downloads works. The problem with collection of files. I'm currently working to fix it.
-
Yes, 1 file downloads works. The problem with collection of files. I'm currently working to fix it.
@Cobra91151
Ok if concurrent download is not a must have, one by one should be fairly
easy to implement if 1 download already works.It sounds like you did it correctly with QList<QFile*> but you never showed
full code after the change so its unclear if just a normal bug-ish or
something with QFtp .
Also the shown connect(ftp, &QFtp::done ) would delete the ftp on first file finished
but assume you fixed that also ? -
@Cobra91151
Ok if concurrent download is not a must have, one by one should be fairly
easy to implement if 1 download already works.It sounds like you did it correctly with QList<QFile*> but you never showed
full code after the change so its unclear if just a normal bug-ish or
something with QFtp .
Also the shown connect(ftp, &QFtp::done ) would delete the ftp on first file finished
but assume you fixed that also ?I will post more code soon. Yes, I have fixed it by creating
closeFtpfunction and connect to it when it finished, so I just need to read more docs on theQQueueand fix the issue with the files.void Test::closeFtp() { qDebug() << "FTP CLOSED"; ftp->close(); ftp->deleteLater(); emit finished(); }I will reply later. Thanks.
-
@Cobra91151
Ok if concurrent download is not a must have, one by one should be fairly
easy to implement if 1 download already works.It sounds like you did it correctly with QList<QFile*> but you never showed
full code after the change so its unclear if just a normal bug-ish or
something with QFtp .
Also the shown connect(ftp, &QFtp::done ) would delete the ftp on first file finished
but assume you fixed that also ?Hi! I have finally fixed it!
My code:
QQueue<QFile*> reportQueue; //initialize the queue connect(ftp, &QFtp::listInfo, [this](const QUrlInfo &ftpUrlInfo) { if (ftpUrlInfo.isFile()) { reportQueue.append(new QFile("local path" + "\\" + ftpUrlInfo.name())); } }); connect(ftp, &QFtp::done, [this]() { emit reportsDataFinished(); }); connect(ftp, &QFtp::commandFinished, [this]() { if (ftp->currentCommand() == QFtp::List) { proceedDownload(); } else if (ftp->currentCommand() == QFtp::Get) { reportFile->close(); reportFile->deleteLater(); proceedDownload(); } }); if (ftp->error() == QFtp::NotConnected) { emit ftpReportError(ftp->error()); } else { ftp->list("ftp path to the dir"); } void Test::proceedDownload() { if (!reportQueue.isEmpty()) { reportFile = reportQueue.dequeue(); reportFile->open(QIODevice::WriteOnly); QFileInfo ftpFileInfo(reportFile->fileName()); ftp->get("ftp path to file" + "/" + ftpFileInfo.fileName(), reportFile, QFtp::Binary); } }I added the files to the
QQueue, when ftplistcommand has been finished, I use functionproceedDownload(). In the function, Idequeue()the queue to thereportFileand proceed with ftpget()function. Whengetftp command finishes, Icloseanddeletethe file from memory, and again call theproceedDownload(). So the the whole process goes again until the queue is empty. I useemit reportsDataFinished();signal in the connection to the slotcloseFtp()where ftp closes anddeleteLater()frees the resources. All files downloads well. Thank you. -
Super :)
Seems pretty compact.