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. QNetworkAccessManager check if file exists
Forum Updated to NodeBB v4.3 + New Features

QNetworkAccessManager check if file exists

Scheduled Pinned Locked Moved Unsolved General and Desktop
19 Posts 6 Posters 1.2k 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.
  • T Thomas 63

    Hi all
    I upload a file using ftp to a destination. That works fine.
    Now I try to check before upöoad, if the file already exists.
    I found the hint that it shold work with NetworkAccessManager->head(request) and read the request->error().
    I do it like this:

            if(QuellFile->open(QIODevice::ReadWrite)){
                QNetworkReply *reply = NetworkAccessManager->head(request);
                qDebug() << reply->error();
                if (reply->error() == QNetworkReply::NoError){
                    reply = NetworkAccessManager->put(request, QuellFile->readAll());
                    connect(reply, &QNetworkReply::uploadProgress, this, &MainWindow::uploadProgress);
                    connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64,qint64)));
                    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
                    meldung("File uploaded.");
                }else{
                    ConfirmDialog dialog("File already exists. Replace?");
                    dialog.exec();
                    if (dialog.getResult()){
                        reply = NetworkAccessManager->put(request, QuellFile->readAll());
                        connect(reply, &QNetworkReply::uploadProgress, this, &MainWindow::uploadProgress);
                        connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64,qint64)));
                        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
                        meldung("File was replaced.");
                    }else{
                        meldung("File was not replaced");
                    }
                }
            }
    
    

    No matter if the file is already exising or not, the reply->error() returns QNetworkReply::NoError.
    What am I doing wrong?

    Thanks in advance,
    Thomas

    C Offline
    C Offline
    ChrisW67
    wrote on last edited by
    #10

    @Thomas-63 This is the response I get from a trivial test case:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QNetworkRequest>
    #include <QObject>
    #include <QTimer>
    
    class Test : public QObject
    {
        Q_OBJECT
    public:
        explicit Test(QObject *p = nullptr)
            : QObject(p)
            , m_nam(new QNetworkAccessManager(this))
        {
            connect(m_nam, &QNetworkAccessManager::finished, this, &Test::receiveReply);
            // does exist
            m_nam->get(QNetworkRequest(QUrl("ftp://test.rebex.net/readme.txt")));
            // does not exist
            m_nam->get(QNetworkRequest(QUrl("ftp://test.rebex.net/missing.txt")));
        }
    
    public slots:
        void receiveReply(QNetworkReply *reply) {
            qDebug() << reply  << reply->error()
                     << reply->request().url()
                     << reply->header(QNetworkRequest::ContentLengthHeader)
                     << reply->header(QNetworkRequest::LastModifiedHeader);
            reply->deleteLater();
        }
    
    private:
        QNetworkAccessManager *m_nam;
    };
    
    int main(int argc, char **argv)
    {
        QCoreApplication app(argc, argv);
        QTimer::singleShot(10000, &app, &QCoreApplication::quit);
        Test t;
        return app.exec();
    }
    #include "main.moc"
    
    15:40:37: Starting /tmp/test/build/Ubuntu_5_15-Debug/test...
    QNetworkReplyImpl(0x5950736b2900) QNetworkReply::NoError QUrl("ftp://test.rebex.net/readme.txt") QVariant(qlonglong, 379) QVariant(QDateTime, QDateTime(2023-09-19 11:12:03.000 AEST Qt::LocalTime))
    QNetworkReplyImpl(0x59507376f3f0) QNetworkReply::ContentNotFoundError QUrl("ftp://test.rebex.net/missing.txt") QVariant(Invalid) QVariant(Invalid)
    

    I have no FTP support in Qt 6 to test with.

    T 1 Reply Last reply
    2
    • C ChrisW67

      @Thomas-63 This is the response I get from a trivial test case:

      #include <QCoreApplication>
      #include <QDebug>
      #include <QNetworkAccessManager>
      #include <QNetworkReply>
      #include <QNetworkRequest>
      #include <QObject>
      #include <QTimer>
      
      class Test : public QObject
      {
          Q_OBJECT
      public:
          explicit Test(QObject *p = nullptr)
              : QObject(p)
              , m_nam(new QNetworkAccessManager(this))
          {
              connect(m_nam, &QNetworkAccessManager::finished, this, &Test::receiveReply);
              // does exist
              m_nam->get(QNetworkRequest(QUrl("ftp://test.rebex.net/readme.txt")));
              // does not exist
              m_nam->get(QNetworkRequest(QUrl("ftp://test.rebex.net/missing.txt")));
          }
      
      public slots:
          void receiveReply(QNetworkReply *reply) {
              qDebug() << reply  << reply->error()
                       << reply->request().url()
                       << reply->header(QNetworkRequest::ContentLengthHeader)
                       << reply->header(QNetworkRequest::LastModifiedHeader);
              reply->deleteLater();
          }
      
      private:
          QNetworkAccessManager *m_nam;
      };
      
      int main(int argc, char **argv)
      {
          QCoreApplication app(argc, argv);
          QTimer::singleShot(10000, &app, &QCoreApplication::quit);
          Test t;
          return app.exec();
      }
      #include "main.moc"
      
      15:40:37: Starting /tmp/test/build/Ubuntu_5_15-Debug/test...
      QNetworkReplyImpl(0x5950736b2900) QNetworkReply::NoError QUrl("ftp://test.rebex.net/readme.txt") QVariant(qlonglong, 379) QVariant(QDateTime, QDateTime(2023-09-19 11:12:03.000 AEST Qt::LocalTime))
      QNetworkReplyImpl(0x59507376f3f0) QNetworkReply::ContentNotFoundError QUrl("ftp://test.rebex.net/missing.txt") QVariant(Invalid) QVariant(Invalid)
      

      I have no FTP support in Qt 6 to test with.

      T Offline
      T Offline
      Thomas 63
      wrote on last edited by Thomas 63
      #11

      @ChrisW67 Hi and thanks for the hints.

      I use this code now:

              QNetworkRequest request(url);
              QNetworkReply *reply = NetworkAccessManager->get(request);
              qDebug() << reply  << reply->error()
                       << reply->request().url()
                       << reply->header(request.ContentLengthHeader)
                       << reply->header(request.LastModifiedHeader);
              if(QuellFile->open(QIODevice::ReadWrite)){
                  if (reply->error() != QNetworkReply::ContentNotFoundError){
                      ConfirmDialog dialog("File exists. Overwrite?");
                      if (dialog.getResult()){
                          reply = NetworkAccessManager->put(request, QuellFile->readAll());
                          connect(reply, &QNetworkReply::uploadProgress, this, &MainWindow::uploadProgress);
                          connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64,qint64)));
                          connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
                          meldung("File replaced");
                      }else{
                          meldung("File not replaced.");
                      }
                  }
              }
      
      

      qDebug() gives me:

      QNetworkReplyImpl(0x6f30350) QNetworkReply::NoError QUrl("ftp://user@ftpserver.ch:21/dokumentation/1_1_1.pdf") QVariant(Invalid) QVariant(Invalid)
      
      
      jsulmJ 1 Reply Last reply
      0
      • T Thomas 63

        @ChrisW67 Hi and thanks for the hints.

        I use this code now:

                QNetworkRequest request(url);
                QNetworkReply *reply = NetworkAccessManager->get(request);
                qDebug() << reply  << reply->error()
                         << reply->request().url()
                         << reply->header(request.ContentLengthHeader)
                         << reply->header(request.LastModifiedHeader);
                if(QuellFile->open(QIODevice::ReadWrite)){
                    if (reply->error() != QNetworkReply::ContentNotFoundError){
                        ConfirmDialog dialog("File exists. Overwrite?");
                        if (dialog.getResult()){
                            reply = NetworkAccessManager->put(request, QuellFile->readAll());
                            connect(reply, &QNetworkReply::uploadProgress, this, &MainWindow::uploadProgress);
                            connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64,qint64)));
                            connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
                            meldung("File replaced");
                        }else{
                            meldung("File not replaced.");
                        }
                    }
                }
        
        

        qDebug() gives me:

        QNetworkReplyImpl(0x6f30350) QNetworkReply::NoError QUrl("ftp://user@ftpserver.ch:21/dokumentation/1_1_1.pdf") QVariant(Invalid) QVariant(Invalid)
        
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #12

        @Thomas-63 Not sure what you're trying to do with your code.
        @ChrisW67 gave you code which is working - did you try it?

        Just as a tip: you should switch to Qt5 connect() syntax.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        T 1 Reply Last reply
        1
        • jsulmJ jsulm

          @Thomas-63 Not sure what you're trying to do with your code.
          @ChrisW67 gave you code which is working - did you try it?

          Just as a tip: you should switch to Qt5 connect() syntax.

          T Offline
          T Offline
          Thomas 63
          wrote on last edited by
          #13

          @jsulm

                  QNetworkRequest request(url); //url is the complete path/name of the destination file i want to write.
                  QNetworkReply *reply = NetworkAccessManager->get(request);
                  qDebug() << reply  << reply->error()
                           << reply->request().url()
                           << reply->header(request.ContentLengthHeader)
                           << reply->header(request.LastModifiedHeader);
                  if(QuellFile->open(QIODevice::ReadWrite)){ // QuellFile is the resource file on my drive
                      if (reply->error() != QNetworkReply::ContentNotFoundError){ //when file does not exist
                          ConfirmDialog dialog("File exists. Overwrite?"); // ask whether to overwrite (this dialog does not show)
                          if (dialog.getResult()){ // response to dialog
                              reply = NetworkAccessManager->put(request, QuellFile->readAll()); // upload file
                              connect(reply, &QNetworkReply::uploadProgress, this, &MainWindow::uploadProgress);
                              connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64,qint64)));
                              connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
                              meldung("File replaced");
                          }else{
                              meldung("File not replaced."); // strangely this message is shown all the time
                          }
                      }
                  }
          
          
          
          JonBJ 1 Reply Last reply
          0
          • T Thomas 63

            @jsulm

                    QNetworkRequest request(url); //url is the complete path/name of the destination file i want to write.
                    QNetworkReply *reply = NetworkAccessManager->get(request);
                    qDebug() << reply  << reply->error()
                             << reply->request().url()
                             << reply->header(request.ContentLengthHeader)
                             << reply->header(request.LastModifiedHeader);
                    if(QuellFile->open(QIODevice::ReadWrite)){ // QuellFile is the resource file on my drive
                        if (reply->error() != QNetworkReply::ContentNotFoundError){ //when file does not exist
                            ConfirmDialog dialog("File exists. Overwrite?"); // ask whether to overwrite (this dialog does not show)
                            if (dialog.getResult()){ // response to dialog
                                reply = NetworkAccessManager->put(request, QuellFile->readAll()); // upload file
                                connect(reply, &QNetworkReply::uploadProgress, this, &MainWindow::uploadProgress);
                                connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64,qint64)));
                                connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
                                meldung("File replaced");
                            }else{
                                meldung("File not replaced."); // strangely this message is shown all the time
                            }
                        }
                    }
            
            
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #14

            @Thomas-63 said in QNetworkAccessManager check if file exists:

                        }else{
                            meldung("File not replaced."); // strangely this message is shown all the time
                        }
            

            If this message is shown all the time it is an else to your

            if (dialog.getResult()){ // response to dialog
            

            so how does that have anything to do with network or file transfer??

            Start by getting rid of your dialog code, you are supposed to produce a small example of the problem.

            T 1 Reply Last reply
            0
            • T Offline
              T Offline
              Thomas 63
              wrote on last edited by
              #15

              If the user selects "no" to the dialog, the file will not be transferred and the message says "File not replaced"

              1 Reply Last reply
              0
              • T Offline
                T Offline
                Thomas 63
                wrote on last edited by
                #16

                my intention was to include the dialog. without it, i all runs nice, but always overwrites the destination file if it exists.

                1 Reply Last reply
                0
                • JonBJ JonB

                  @Thomas-63 said in QNetworkAccessManager check if file exists:

                              }else{
                                  meldung("File not replaced."); // strangely this message is shown all the time
                              }
                  

                  If this message is shown all the time it is an else to your

                  if (dialog.getResult()){ // response to dialog
                  

                  so how does that have anything to do with network or file transfer??

                  Start by getting rid of your dialog code, you are supposed to produce a small example of the problem.

                  T Offline
                  T Offline
                  Thomas 63
                  wrote on last edited by
                  #17

                  @JonB
                  Why does the block

                          qDebug() << reply  << reply->error()
                                   << reply->request().url()
                                   << reply->header(request.ContentLengthHeader)
                                   << reply->header(request.LastModifiedHeader);
                  
                  

                  give me QVariant(Invalid) QVariant(Invalid) for the header() - parts?

                  C 1 Reply Last reply
                  0
                  • T Thomas 63

                    @JonB
                    Why does the block

                            qDebug() << reply  << reply->error()
                                     << reply->request().url()
                                     << reply->header(request.ContentLengthHeader)
                                     << reply->header(request.LastModifiedHeader);
                    
                    

                    give me QVariant(Invalid) QVariant(Invalid) for the header() - parts?

                    C Offline
                    C Offline
                    ChrisW67
                    wrote on last edited by
                    #18

                    @Thomas-63

                    Why does the block

                        qDebug() << reply  << reply->error()
                                 << reply->request().url()
                                 << reply->header(request.ContentLengthHeader)
                                 << reply->header(request.LastModifiedHeader);
                    

                    give me QVariant(Invalid) QVariant(Invalid) for the header() - parts?

                    In the position you have this in your code the GET request has not been sent and thus the reply object has not yet been populated i.e., nothing to display. Qt networking is, by default, asynchronous. The request will not be sent until the Qt event loop is reached. You need to reorganise your code to handle the async nature of Qt networking.

                    BTW, why a GET and not a HEAD?

                    I tried your example site in my code and got:

                    QNetworkReplyImpl(0x5a7cc54c6120) QNetworkReply::ConnectionRefusedError QUrl("ftp://user@ftpserver.ch:21/dokumentation/1_1_1.pdf") QVariant(Invalid) QVariant(Invalid)
                    

                    You have not shared if my code ran as-is on your system.

                    C 1 Reply Last reply
                    2
                    • C ChrisW67

                      @Thomas-63

                      Why does the block

                          qDebug() << reply  << reply->error()
                                   << reply->request().url()
                                   << reply->header(request.ContentLengthHeader)
                                   << reply->header(request.LastModifiedHeader);
                      

                      give me QVariant(Invalid) QVariant(Invalid) for the header() - parts?

                      In the position you have this in your code the GET request has not been sent and thus the reply object has not yet been populated i.e., nothing to display. Qt networking is, by default, asynchronous. The request will not be sent until the Qt event loop is reached. You need to reorganise your code to handle the async nature of Qt networking.

                      BTW, why a GET and not a HEAD?

                      I tried your example site in my code and got:

                      QNetworkReplyImpl(0x5a7cc54c6120) QNetworkReply::ConnectionRefusedError QUrl("ftp://user@ftpserver.ch:21/dokumentation/1_1_1.pdf") QVariant(Invalid) QVariant(Invalid)
                      

                      You have not shared if my code ran as-is on your system.

                      C Offline
                      C Offline
                      ChrisW67
                      wrote on last edited by
                      #19

                      Something along these lines might work (untested):

                      class Uploader : public QObject
                      {
                          Q_OBJECT
                      public:
                          explicit Uploader(QObject *p = nullptr)
                              : QObject(p)
                              , m_nam(new QNetworkAccessManager(this))
                          {
                          }
                      
                          void upload(const QUrl& target, const QString &file) {
                              m_target = target;
                              m_file = file;
                              QNetworkReply *headReply = m_nam->head(QNetworkRequest(m_target));
                              connect(headReply, &QNetworkReply::finished, this, &Uploader::receiveHeadReply);
                              // connect error signals etc...
                          }
                      
                      public slots:
                          void receiveHeadReply(QNetworkReply *reply) {
                              qDebug() << Q_FUNC_INFO
                                       << reply->error()
                                       << reply->request().url()
                                       << reply->header(QNetworkRequest::ContentLengthHeader)
                                       << reply->header(QNetworkRequest::LastModifiedHeader);
                      
                              bool upload = false;
                              if (reply->error() == QNetworkReply::NoError) {
                                  // file exists
                                  // prompt for overwrite
                                  // if yes then
                                  upload = true;
                              }
                              else if (reply->error() == QNetworkReply::ContentNotFoundError) {
                                  qDebug() << "Not there so we can upload";
                                  upload = true;
                              }
                              else {
                                  // some other error condition we need to handle or ignore
                              }
                              reply->deleteLater();
                      
                              if (upload) {
                                  // open m_file, read data, send data
                                  QByteArray data;
                                  QNetworkReply *putReply = m_nam->put(QNetworkRequest(m_target), data);
                                  connect(putReply, &QNetworkReply::finished, this, &Uploader::receivePutReply);
                              }
                      
                          }
                          void receivePutReply(QNetworkReply *reply)    {
                              qDebug() << Q_FUNC_INFO
                                       << reply->error()
                                       << reply->request().url();
                              reply->deleteLater();
                          }
                      
                      private:
                          QNetworkAccessManager *m_nam;
                          QUrl m_target;
                          QString m_file;
                      };
                      
                      1 Reply Last reply
                      0

                      • Login

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