【发布时间】:2017-01-21 23:17:27
【问题描述】:
我正在开发一个应用程序,它需要使用 QT (5.6.1)
将大量文件从一个文件夹复制到另一个文件夹为此,我一直在使用QFile::copy() 方法。这很好用,除了一件事:它非常慢。使用 Windows 资源管理器执行相同复制操作所需时间的两倍以上。
想知道这是为什么,我深入研究了 QT 源代码,并在qfile.cpp 中找到了这个,看起来很相关:
char block[4096];
qint64 totalRead = 0;
while(!atEnd()) {
qint64 in = read(block, sizeof(block));
if (in <= 0)
break;
totalRead += in;
if(in != out.write(block, in)) {
close();
d->setError(QFile::CopyError, tr("Failure to write block"));
error = true;
break;
}
}
所以,据我了解,复制操作使用的是 4096 字节的缓冲区。这对于复制操作来说非常小,很可能是问题的原因。 所以我所做的就是将缓冲区的大小更改为:
char block[4194304]; // 4MB buffer
然后我重建了整个 QT 库以包含此更改。但是,所做的所有修改都完全打破了该方法。现在,当我的应用程序尝试调用 QFile::Copy() 时,操作会立即中断(该方法甚至没有开始运行,根据 QtCreator 的调试器在第一行之前停止)。调试器告诉我:
The inferior stopped because it received a signal from the Operating System.
Signal name :
SIGSEGV
Signal meaning :
Segmentation fault
我的 c++ 有点生疏了,但我不明白如何仅仅更改数组的分配大小就可以完全破坏方法...任何人都可以提供帮助:
1) 告诉我为什么 QFile:Copy() 这么慢(我错过了什么吗?它不仅在我的 PC 上,在几台不同的机器上测试过)。罪魁祸首实际上是我在上面发布的代码还是完全是其他东西? 2) 告诉我为什么一个更改完全破坏了 QFile
【问题讨论】:
-
在 qtbase (
tests/benchmarks/corelib/io/qfile) 中有一个基准测试,它尝试使用不同的块大小在 Win32 上读取文件。我不确定为什么普遍选择 4K。也许这取决于硬盘技术?您可以尝试运行基准测试(readBigFile_Win32测试功能)并检查吗? -
在 Windows 上,最好的办法是使用 CopyFileEx,请参阅带有进度指示的 this complete example :)