Accessing files from a file server with a cross-platform app
Page |
1 |
This is not directly Qt related, but I’m hoping there might be a clever solution:
In my cross-platform app I need to open a well known (meaning the user doesn’t select it) file located on a file server (using QFile).
The file server is running under Windows 2003 server.
Under windows, I can use UNC notation (\\FILESRV\myShare\myFile).
Under Linux and Mac, I need to mount the share from what I understand (using smb) , but that would mean the path will be different on each platform.
Has anyone had to deal with something like this?
19 replies
You can store filePath in one string and for *nix remove filename from it and run QProcess with smbclient
Something like this (not tested, maybe not even compiling)
- int lastDelimiterIndex = path.lastIndexOf("\\");
So you will have in shareName name of share (first arg for smbclient) and in fileName you will have file name (part of second arg for smbclient)
Well the problem is that Qt is very limited (to my knowledge) in this respect.
Whereas in Obj-C there are truly great functions where one can easily load the contents of a url (which can be anything) in a string (through functions like initWithContentsOfURL) or file (with fileHandleForReadingFromURL), I’m surprised there are no such functions in the generally rich classes of QString and QFile.
The best I’ve managed to do when I have to do something similar, is use a helper function like
- {
- QNetworkAccessManager manager;
- QEventLoop loop;
- loop.exec();
- QMessageBox::information(this, tr("Download file"), tr("Unable to save the file %1: %2.").arg(fname).arg(tf->errorString()));
- delete tf;
- };
- tf->write(reply->readAll());
- delete reply;
- tf->flush();
- tf->close();
- delete tf;
- return fi.canonicalFilePath();
- }
to generate a temporary copy of a file locally, and then use the filename this function returns as an argument to QFile.
I’m pretty sure my implementation is terrible and that’s why I would like to avoid this approach, but I haven’t been able to come up with something better.
What do you need to do with the file(s) after you get access to them? Why are you saving it locally in the above example? It would be more efficient just to read from the QNetworkReply into whatever data structure is appropriate.
Also, please be aware that using local event loops like this are (in general) a bad idea. Other events are still processed which could result in your instance of MyHelperClass being deleted, then when your local event loop exits you are into the realms of undefined behaviour.
I need an actual filepath in this case, because it is passed to a 3rd party library (which uses QFile open as far as I know).
I’m pretty sure my function does not work without the loop.exec() call, and that’s why I added it.
That is why I mentioned I’m surprised that there is no helper function to perform such a common ( I would think) task.
Your function does not work without the local event loop as you are trying to use QNAM in a synchronous manner when it is designed for asynchronous use. The easiest way is to connect a slot up to the finished() signal of QNetworkReply. Something like this:
- {
- QNetworkRequest request;
- request.setUrl( url );
- connect( reply, SIGNAL( finished() ),
- SLOT( processReply() ) );
- }
where m_nam is a pointer to your application’s QNetworkAccessManager. Then in the two referenced slots you either handle the reply as you do in your example function or you handle the error.
There are also other signals that you can connect to. These allow you to show download progrerss for example or to check the http metadata (e.g. response code).
You must log in to post a reply. Not a member yet? Register here!



