Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Download multiple files from Ftp issue
Forum Updated to NodeBB v4.3 + New Features

Download multiple files from Ftp issue

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 2.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Cobra91151C Offline
    Cobra91151C Offline
    Cobra91151
    wrote on last edited by Cobra91151
    #1

    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 QFile as 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 deleteLater for all files in the ftp directory. Any ideas how to do it? Thanks.

    JonBJ 1 Reply Last reply
    0
    • Cobra91151C Cobra91151

      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 QFile as 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 deleteLater for all files in the ftp directory. Any ideas how to do it? Thanks.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @Cobra91151
      How are you waiting for one file's get() to finish, before you set off the next one? You are reusing the same reportFile variable over & over, while it is still servicing previous file get()s? Hence you only get the final file, and the crashes when one file's reportFile.close(); closes/deletes the reportFile from a different file!? (Put a qDebug() in the first connect(), 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.

      Cobra91151C 1 Reply Last reply
      4
      • JonBJ JonB

        @Cobra91151
        How are you waiting for one file's get() to finish, before you set off the next one? You are reusing the same reportFile variable over & over, while it is still servicing previous file get()s? Hence you only get the final file, and the crashes when one file's reportFile.close(); closes/deletes the reportFile from a different file!? (Put a qDebug() in the first connect(), 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.

        Cobra91151C Offline
        Cobra91151C Offline
        Cobra91151
        wrote on last edited by
        #3

        @JonB

        Ok. I will change code and reply. Thanks.

        1 Reply Last reply
        0
        • Cobra91151C Offline
          Cobra91151C Offline
          Cobra91151
          wrote on last edited by
          #4

          I have tried to use QList<QFile*> and append the files when they are listing, and then loop it, and when command get() finished, close and deleteLater() the file, now it doesn't crash when use QFile as 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 QQueue and proceed the file one by one.

          mrjjM 1 Reply Last reply
          0
          • Cobra91151C Cobra91151

            I have tried to use QList<QFile*> and append the files when they are listing, and then loop it, and when command get() finished, close and deleteLater() the file, now it doesn't crash when use QFile as 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 QQueue and proceed the file one by one.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            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.

            Cobra91151C 1 Reply Last reply
            0
            • mrjjM mrjj

              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.

              Cobra91151C Offline
              Cobra91151C Offline
              Cobra91151
              wrote on last edited by
              #6

              @mrjj

              Yes, 1 file downloads works. The problem with collection of files. I'm currently working to fix it.

              mrjjM 1 Reply Last reply
              0
              • Cobra91151C Cobra91151

                @mrjj

                Yes, 1 file downloads works. The problem with collection of files. I'm currently working to fix it.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @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 ?

                Cobra91151C 2 Replies Last reply
                1
                • mrjjM mrjj

                  @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 ?

                  Cobra91151C Offline
                  Cobra91151C Offline
                  Cobra91151
                  wrote on last edited by
                  #8

                  @mrjj

                  I will post more code soon. Yes, I have fixed it by creating closeFtp function and connect to it when it finished, so I just need to read more docs on the QQueue and fix the issue with the files.

                  void Test::closeFtp()
                  {
                      qDebug() << "FTP CLOSED";
                      ftp->close();
                      ftp->deleteLater();
                      emit finished();
                  }
                  

                  I will reply later. Thanks.

                  1 Reply Last reply
                  1
                  • mrjjM mrjj

                    @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 ?

                    Cobra91151C Offline
                    Cobra91151C Offline
                    Cobra91151
                    wrote on last edited by
                    #9

                    @mrjj

                    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 ftp list command has been finished, I use function proceedDownload(). In the function, I dequeue() the queue to the reportFile and proceed with ftp get() function. When get ftp command finishes, I close and delete the file from memory, and again call the proceedDownload(). So the the whole process goes again until the queue is empty. I use emit reportsDataFinished(); signal in the connection to the slot closeFtp() where ftp closes and deleteLater() frees the resources. All files downloads well. Thank you.

                    1 Reply Last reply
                    2
                    • mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Super :)
                      Seems pretty compact.

                      1 Reply Last reply
                      2

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved