我正在开发一个应用程序,需要使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,据我所知,复制操作使用4096字节的缓冲区.这对于复制操作来说非常小,很可能是问题的原因.所以我做的是将缓冲区的大小更改为:
char block[4194304]; // 4MB buffer
Run Code Online (Sandbox Code Playgroud)
然后我重建了整个QT库以包含此更改.但是,所有的修改都完全打破了这个方法.现在,当我的应用程序尝试调用QFile :: Copy()时,操作立即中断(方法甚至没有开始运行,根据QtCreator的调试器在第一行之前停止).调试器告诉我:
The inferior stopped because it received a signal from the Operating System.
Signal name :
SIGSEGV
Signal meaning :
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
我的c ++有点生疏,但我不明白改变数组的分配大小如何完全打破方法......任何人都可以帮助:
1)告诉我为什么QFile:Copy()是如此之慢(我错过了什么?它不只是在我的电脑上,在几台不同的机器上测试过).实际上是我上面发布的代码还是完全不同的代码?2)告诉我为什么一个改变完全破坏了QFile
您的更改破坏QFile的原因是4M缓冲区不适合堆栈(默认堆栈大小通常类似于1M).快速解决方案是:
std::vector<char> vec(4*1024*1024);
char *block = &vec.front();
Run Code Online (Sandbox Code Playgroud)
向量将在堆上分配大缓冲区(并在完成后负责解除分配),并且您只需指向block向量的前面.
我认为您对复制缓慢的原因的分析是现场.