【问题标题】:Qt: How to lock/prevent a file from being read while it is written?Qt:如何在写入时锁定/防止文件被读取?
【发布时间】:2015-11-19 13:54:15
【问题描述】:

我在 Windows 7 上使用 Qt5。
在我当前的项目中,我打开一个二进制文件,以便用来自 TCP 套接字的数据填充它。 通常,在填充文件后,我将其关闭,另一个应用程序将读取此二进制文件以进行进一步处理。
好吧,问题是:写入操作大约需要 4-5 秒(甚至更多),所以我需要找到一种方法阻止其他应用程序从二进制文件中读取,直到文件完全填充...
下面是代码(但我想它不会有太大帮助):

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();

我正在考虑使用一个临时文件,并在写操作完成后重命名它。
但也许还有另一个更好/更聪明的想法?某种“锁定文件以供阅读”可能......?

【问题讨论】:

    标签: qt file concurrency locking read-write


    【解决方案1】:

    如果您拥有两个应用程序的源,那么写入文件的那个可以通过许多 IPC 机制之一(例如本地套接字)向另一个应用程序发出它已完成写入的信号。

    或者,写入具有不同文件名的文件,然后在写入完成后将文件重命名/复制到读取应用程序预期的位置。

    但是,写出文件时建议使用QSaveFile,而不是QFile。正如文档所述:-

    在写入的时候,内容会被写入一个临时文件,如果没有出错,commit()会移动到最终文件中

    所以这可能会为您解决问题。

    【讨论】:

    • 似乎 QSaveFile 使用了与最终文件位于同一文件夹中的临时文件... 你知道这个临时文件名是否唯一吗?我问这个是因为我我的应用程序中有很多线程,所有这些线程都会尝试对位于同一文件夹中的文件使用 QSaveFile 变量!
    • 文件权限”能否在 Windows7 下工作...?你知道的,像 QFileDevice::ReadUser 等等。
    • Windows 不完全支持权限。权限文档有一些警告:doc.qt.io/qt-5/qfiledevice.html#Permission-enum
    • 另一种方法:Windows 应用程序是否可以确定某个文件是否已打开以供另一个应用程序/进程写入?我想每个文件都必须有一些相关的标志/属性......
    • @groenhen,这将是一个不同的问题,您应该在 SO 上提出,特别是当 OP 的问题涉及 Qt 时,因此仅 Windows 的解决方案并不理想。
    【解决方案2】:

    我知道可能有点晚了,但我最近发现了一个有趣的解决方案,即一个名为“Locked File”的组件:

    QtLockedFile 类扩展了 QFile 的建议锁定功能。

    这个类扩展了 QFile 类,带有进程间文件锁定 能力。如果一个应用程序要求多个进程应该 访问同一个文件,可以使用 QtLockedFile 轻松确保 一次只有一个进程正在写入文件,并且没有进程 正在写入,而其他人正在阅读它。

    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;
    };
    

    这个链接会带你到正确的地方,QLockedFile 类的实现是:
    https://github.com/kbinani/qt-solutions/tree/master/qtlockedfile

    ** 所以,我决定分享这个信息,也许其他 Qt 用户有兴趣! **

    【讨论】:

    • 过去曾尝试为Android 重写QLockedFile 库,但至少它适用于windowslinux
    猜你喜欢
    • 1970-01-01
    • 2019-11-13
    • 2019-10-01
    • 2023-03-23
    • 1970-01-01
    • 2013-08-06
    • 2020-04-19
    • 1970-01-01
    • 2015-05-09
    相关资源
    最近更新 更多