2

I am using Qt5 on Windows 7.
In my current project I open a binary file in order to populate it with data coming from a TCP socket. Normally, after the file is populated, I close it and another application will read this binary file for further processing.
Well, the problem is: The writing operation takes about 4-5 seconds (or even more) so I need to find a way to prevent the other application from reading from the binary file until the file is completely populated...
Here below is the code (yet I suppose it won't help much):

int error = 0;
unsigned long dataLength;
char dataBuffer[1500];
QFile localFile("datafile.bin");
//
localFile.open(QIODevice::WriteOnly);
while(error == 0)
{
    error = readSocket(dataBuffer, &dataLength);
    if(error == 0)
    {
        localFile.write(dataBuffer, dataLength);
    }
    else
    {
        error = -1;
    }
}
localFile.close();

I am thinking about using a temporary file and rename it after the write operation is complete.
But maybe there is another better/smarter idea? Some kind of "lock file for reading" maybe...?

סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68

2 Answers2

5

If you have the source to both applications, then the one writing the file can signal the other application by one of many IPC mechanisms (e.g. local sockets) that it has finished writing.

Alternatively, write to a file with a different filename and then rename / copy the file to the location expected by the reading application, when the write has finished.

However, it is advisable to use QSaveFile, rather than QFile when writing out files. As the documentation states: -

While writing, the contents will be written to a temporary file, and if no error happened, commit() will move it to the final file

So this will likely solve the problem for you.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • It seems QSaveFile uses a temporary file in the same folder as the final file... **Do you know if this temporary file name is unique?** I am asking this because I have many threads in my app, and all these threads will try to use QSaveFile variables for files located in the same folder! – סטנלי גרונן Nov 19 '15 at 18:00
  • Would "_file permissions_" work under Windows7...? You know, something like **QFileDevice::ReadUser**, etc. – סטנלי גרונן Nov 19 '15 at 19:46
  • Permissions are not *fully* supported in Windows. The permissions documentation has some of the caveats: http://doc.qt.io/qt-5/qfiledevice.html#Permission-enum – Nicolas Holthaus Nov 19 '15 at 21:42
  • A different approach: Is it possible for a Windows application to find out if a certain file is already open for writing by another app/process? I guess there must be some related flags/attributes for each file... – סטנלי גרונן Dec 03 '15 at 13:12
  • @groenhen, that would be a different question which you should pose on SO, especially as the OP's question concerns Qt, so a Windows only solution is not ideal. – TheDarkKnight Dec 03 '15 at 13:20
5

I know maybe it's a little bit too late, but I recently found an interesting solution, i.e. a component named "Locked File":

The QtLockedFile class extends QFile with advisory locking functions.

This class extends the QFile class with inter-process file locking capabilities. If an application requires that several processes should access the same file, QtLockedFile can be used to easily ensure that only one process at a time is writing to the file, and that no process is writing to it while others are reading it.

class QtLockedFile : public QFile
{
public:
    enum LockMode { NoLock = 0, ReadLock, WriteLock };

    QtLockedFile();
    QtLockedFile(const QString &name);
    ~QtLockedFile();

    bool open(OpenMode mode);

    bool lock(LockMode mode, bool block = true);
    bool unlock();
    bool isLocked() const;
    LockMode lockMode() const;

private:
    LockMode m_lock_mode;
};

This link will lead you to the right place, where the QLockedFile class implementation is:
https://github.com/kbinani/qt-solutions/tree/master/qtlockedfile

** So, I decided to share this info, maybe other Qt-users are interested! **

סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
  • have tried to rewrite `QLockedFile` library for `Android` in the past but at least it works in `windows` and `linux` – Top-Master Oct 14 '18 at 05:11