QNetworkAccessManager check if file exists
-
First of all, thank you for the tip with the double signal.
I admit I am a programming hobbyist and sometimes I copy snippets.
In this case i did not see that it was redundant.Do you have a hint on how to check if a file already exists?
@Thomas-63 said in QNetworkAccessManager check if file exists:
Do you have a hint on how to check if a file already exists?
-
@Thomas-63 said in QNetworkAccessManager check if file exists:
Do you have a hint on how to check if a file already exists?
-
First of all, thank you for the tip with the double signal.
I admit I am a programming hobbyist and sometimes I copy snippets.
In this case i did not see that it was redundant.Do you have a hint on how to check if a file already exists?
@Thomas-63 said in QNetworkAccessManager check if file exists:
Do you have a hint on how to check if a file already exists?
Print the reply you get from
head(request)
and check if there is any information in it, like "File exists" or if the header already contains the same filename as the file you want to upload...
Then you can think of a way how you handle it.See the answer here.
In any case, checking for Qt errors won't help at all, because as I've said above, the requests/replies are working properly. -
@Thomas-63 said in QNetworkAccessManager check if file exists:
Do you have a hint on how to check if a file already exists?
Print the reply you get from
head(request)
and check if there is any information in it, like "File exists" or if the header already contains the same filename as the file you want to upload...
Then you can think of a way how you handle it.See the answer here.
In any case, checking for Qt errors won't help at all, because as I've said above, the requests/replies are working properly. -
@Pl45m4 The answer from reply->error() is: QNetworkReply::NoError
QNetworkReply *reply = NetworkAccessManager->head(request); qDebug() << reply->error();
@Thomas-63 said in QNetworkAccessManager check if file exists:
The answer from reply->error() is: QNetworkReply::NoError
I said
reply
notreply->error()
.Maybe you can make use of
reply->rawHeader()
and print/parse the output manually to get an overview of the information you actually receive from the server.Btw: @moderators I found a bug in the documentation.
https://doc.qt.io/qt-6/qnetworkreply.html#header
should link toQVariant QNetworkReply::header(QNetworkRequest::KnownHeaders header) const
, but you land at the top of the page where theQNetworkReply
header file is mentioned. -
@Thomas-63 said in QNetworkAccessManager check if file exists:
The answer from reply->error() is: QNetworkReply::NoError
I said
reply
notreply->error()
.Maybe you can make use of
reply->rawHeader()
and print/parse the output manually to get an overview of the information you actually receive from the server.Btw: @moderators I found a bug in the documentation.
https://doc.qt.io/qt-6/qnetworkreply.html#header
should link toQVariant QNetworkReply::header(QNetworkRequest::KnownHeaders header) const
, but you land at the top of the page where theQNetworkReply
header file is mentioned.@Pl45m4 Then problem with
#header
is known but no fix yet. -
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@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.
-
@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.
@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)
-
@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)
@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.
-
@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.
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 } } }
-
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 } } }
@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 yourif (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.
-
@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 yourif (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.
-
@JonB
Why does the blockqDebug() << reply << reply->error() << reply->request().url() << reply->header(request.ContentLengthHeader) << reply->header(request.LastModifiedHeader);
give me QVariant(Invalid) QVariant(Invalid) for the header() - parts?
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.
-
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.
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; };