使用Qt禁用文件复制缓冲

使用Qt禁用文件复制缓冲,qt,file,winapi,Qt,File,Winapi,我正在使用Qt框架编写一个文件复制器数据备份软件,并且在数据复制中遇到了一个“缺陷” 如果我将数据从SSD复制到HDD,SSD读取数据的速度要比HDD写入数据的速度快得多。因此,读取的数据在写入HDD之前会填充缓冲区 这不会是一个问题,除非当缓冲区被填满时,数据复制的进度表会暂停,然后当它被清空时,它会再次被填满。因此,进度表指示一系列进度,然后它暂停,然后它指示进度,然后暂停,等等。与以恒定速率写入数据时发生的恒定进度相比,它看起来相当丑陋 Qt有办法解决这个问题吗?我试着使用QFile::f

我正在使用Qt框架编写一个文件复制器数据备份软件,并且在数据复制中遇到了一个“缺陷”

如果我将数据从SSD复制到HDD,SSD读取数据的速度要比HDD写入数据的速度快得多。因此,读取的数据在写入HDD之前会填充缓冲区

这不会是一个问题,除非当缓冲区被填满时,数据复制的进度表会暂停,然后当它被清空时,它会再次被填满。因此,进度表指示一系列进度,然后它暂停,然后它指示进度,然后暂停,等等。与以恒定速率写入数据时发生的恒定进度相比,它看起来相当丑陋

Qt有办法解决这个问题吗?我试着使用
QFile::flush()
,但没用

我们有来自Win32 api的
FlushFileBuffers
,但文档中说,在每次写入磁盘驱动器设备之后,如果单独执行许多写入操作,则使用它的效率很低

我们可以使用
FILE\u FLAG\u NO\u BUFFERING
FILE\u FLAG\u WRITE\u通过
标志调用
CreateFile
函数,但是有没有办法通过
QFile
实现这一点

然后我们可以选择完全关闭目标磁盘的缓存

最优雅的解决方案是什么

以下是相关代码:

QFile sourceFile;
QFile targetTempFile;
// ...
QByteArray buffer;
for (int count = 0; !(buffer = sourceFile.read(1000000)).isEmpty() && cancel == false; count++)
{
    int readSize = buffer.size();
    targetTempFile.write(buffer);
    //targetTempFile.flush();
    setProgressMeters(readSize, fileSize, jobSize);
    setTimeLabels(startTime.elapsed(),readSize);
}

要在Windows上执行文件复制,应使用
CopyFileEx
,而不是
QFile
CopyFileEx
将使用较低级别的API,这可能导致在现代硬件上实现零拷贝复制。看


要从
QFileDevice
(即
QFile
/
QSaveFile
)获取本机
HANDLE
,并在
QFile
上使用
重新打开文件
,请参阅。

@JoshOrenberg winapi函数上的
a
W
后缀与
char
接口有关。现代的默认设置是将
ApiW
别名为
Api
,例如,
CopyFileEx
CopyFileExW
相同。那么CopyFile2呢?它只是一个参数结构不同的CopyFileEx吗?如果通过worker->moveToThread(workerThread)从移动到工作线程的工作对象运行,如何将CopyFileEx示例修改为线程安全的;呼叫?@JoshOrenberg这个问题不属于这里-在你想看到修改的地方提问。但一般来说,
Copier
本质上是线程安全的,因为它在内部使用工作线程-c.f.
QtConcurrent::run
。将
复印机
移动到任何其他线程都没有意义。