c++ - Qt5 QFile::close() 写入速度非常慢

标签 c++ qt qt5 qfile

我使用 QFile 作为文件读取器和文件写入器,将文件从我的应用程序内部复制到 USB。我一直在试图弄清楚为什么我的文件复制到 USB(带有进度条)需要这么长时间。我终于发现,当我关闭用于写入的 QFile 对象时,close() 操作可能会占用实际写入操作所花费的时间。这些文件非常大,我读/写了 16384 字节的 block ,然后我向 GUI 发送信号以增加用户查看的进度条。我最终在每次写入后添加了对 flush() 的调用,因为我认为这是输出流实际上尚未写入磁盘的结果。那并没有什么不同。传出 QFile 对象的关闭仍然比写入时间似乎要长得多(复制前后以及每次 QFile::close() 调用之前和之后的时间,时间代码已被删除易于阅读,我也调试并看到它发生了)。当然,不调用 close() 函数也无济于事,因为 QFile 对象的破坏导致它被调用。

我的代码如下(减去错误检查、目标空间检查等):

void FileCopy::run()
{
    QByteArray bytes;
    int totalBytesWritten = 0;
    int inListSize = inList.size();

    for (int i=0; !canceled && i<inListSize; i++)
    {
        QString inPath = inList.at(i).inPath;
        QString outPath = inList.at(i).outPath;
        QFile inFile(inPath);
        QFile outFile(outPath);
        int filesize = inFile.size();
        int bytesWritten = 0;

        if (!inFile.open(QIODevice::ReadOnly))
        {
            return;
        }

        if (!outFile.open(QIODevice::WriteOnly))
        {
            inFile.close();
            return;
        }

        // copy the FCS file with progress
        while (!canceled && bytesWritten < filesize)
        {
            bytes = inFile.read(MAXBYTES);
            qint64 outsize = outFile.write(bytes);
            outFile.flush();
            if (outsize != bytes.size())
            {
                break;
            }
            bytesWritten += outsize;
            totalBytesWritten += outsize;
            Q_EMIT signalBytesCopied(totalBytesWritten, i+1, inListSize);
            QThread::usleep(100); // allow time for detecting a cancel
        }

        inFile.close();
        outFile.close();
    }

    // Other error checking done here
}

任何人都可以找到通过此方法的方法吗?我实际上更希望进度条移动得更慢,更准确地向用户显示拷贝的状态,而不是让进度条在不到复制和接近实际完成所需时间的一半时间内读取 100%。

我也尝试过使用 QSaveFile 而不是 QFile 来输出,但是 QSaveFile::commit() 有同样的问题,提交比完成实际的复制循环花费更多的时间。我认为这是因为,在底层,它使用与 QFile 相同的功能,派生自 QIoDevice。

我考虑过改用标准流,但希望在此应用程序中保持文件处理方式的一致性。不过,如果 QFile::close() 需要这么长时间才能关闭,这是有可能的。或者标准流是否可能有同样的问题?

我正在使用 Qt5.1.1 和 Qt 1.2.2 VS 加载项开发带有 VS2010 的 Win7 32 位机器。感谢您的任何建议。

最佳答案

当您正在编写时,操作系统可能只是将写入缓存在内存中(快速)。但是当您关闭文件时,它必须将所有数据刷新到磁盘(慢 - 特别是如果它还没有实际写入任何数据)。因此关闭文件必须等待操作系统实际将所有数据放到磁盘 (USB) 上,而那时可能实际上是所有数据。

操作系统这样做的原因当然是为了加快写入速度——而且通常它们可以在没有其他事情发生时在后台将数据刷新到磁盘(所以你不会真正注意到实际成本,因为它是在没有其他事情发生的情况下随着时间摊销的)。但是,如果您只是编写然后立即关闭,您就会注意到。 注意:另一种方法是写入调用速度变慢 - 您最终仍会花费相同的实际时间。

关于c++ - Qt5 QFile::close() 写入速度非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38513993/

相关文章:

c++ - 如何区分客户端是从服务器端使用 TCP 还是 UDP

c++ - 负 8 位 int 的 Qt 十六进制表示?

c++ - qtreewidget 中的可变列号

qt - 在 Qt5 中使用文本元素的彩色点

c++ - 为什么没有 QTransform::fromRotate?

c++ - 在 Mac Os X 上使用 CGEvent 和 Qt

c++ - 为什么 std::sort 不使用我的 operator< 实现

c++ - QFileDialog 中的后退和前进按钮没有信号

c++ - MainWindow 是否在 qt5 中自行初始化?

c++ - 在带有启用自动换行的标签的 QFormLayout 中,四分之一的布局会变得乏味