2

我需要将 a 分块复制QFile到另一个QFile,所以我不能使用QFile::copy. 这是最原始的实现:

bool CFile::copyChunk(int64_t chunkSize, const QString &destFolder)
{
    if (!_thisFile.isOpen())
    {
        // Initializing - opening files
        _thisFile.setFileName(_absoluteFilePath);
        if (!_thisFile.open(QFile::ReadOnly))
            return false;

        _destFile.setFileName(destFolder + _thisFileName);
        if (!_destFile.open(QFile::WriteOnly))
            return false;
    }

    if (chunkSize < (_thisFile.size() - _thisFile.pos()))
    {
        QByteArray data (chunkSize, 0);
        _thisFile.read(data.data(), chunkSize);
        return _destFile.write(data) == chunkSize;
    }
}

从这个片段中不清楚,但我只打算将一个二进制文件作为一个整体复制到另一个位置,只是以块的形式,这样我就可以为大文件提供进度回调和取消工具。

另一个想法是使用内存映射。我是不是该?如果是这样,那么我应该只映射源文件并仍然使用_destFile.write,还是应该同时映射并使用memcpy

我想这个问题与 Qt 并没有真正的联系,我认为答案应该适用于任何支持内存映射的文件 I/O API。

4

3 回答 3

3

好的,好的,如果它必须是内存映射解决方案。这是一个:

QFile source("/tmp/bla1.bin");
source.open(QIODevice::ReadOnly);
QFile destination("/tmp/bla2.bin");
destination.open(QIODevice::ReadWrite);
destination.resize(source.size());
uchar *data = destination.map(0,destination.size());
if(!data){
    qDebug() << "Cannot map";
    exit(-1);
}
QByteArray buffer;
int chunksize = 200;
int var = 0;
do{
    var = source.read((char *)(data), chunksize);
    data += var;
}while(var > 0);
destination.unmap(data);
destination.close();

这仅将目标文件映射到内存中。我怀疑映射源文件也会有很大的不同。但这是用于具体测量的东西,而不是假设。

另一个问题是您是否可以一次将整个文件映射到内存中。不断地取消映射和重新映射肯定会降低性能。即使你使用 Qt。内存映射之类的函数在不同平台上的行为往往会令人不安,例如,您映射到内存的最大文件大小可能不同。

于 2013-08-18T17:58:02.273 回答
1

最佳方法是什么,总是在旁观者的眼中。这是至少一种更短的工作方法:

QFile source("/tmp/bla1.bin");
source.open(QIODevice::ReadOnly);
QFile destination("/tmp/bla2.bin");
destination.open(QIODevice::WriteOnly);
QByteArray buffer;
int chunksize = 200; // Whatever chunk size you like
while(!(buffer = source.read(chunksize)).isEmpty()){
    destination.write(buffer);
}
destination.close();
source.close();

还有内存映射……我尽量远离这样的事情。我永远不太确定它们是如何独立于平台的。

于 2013-08-18T17:02:13.510 回答
-1

使用这个 QFile::map() 方法:

QFile fs("Sourcefile.bin");

fs.open(QFile::ReadOnly);

QFile fd("Destinationfile.bin");

fd.open(QFile::WriteOnly);

fd.write((char*) fs.map(0, fs.size()), fs.size()); //Copies all data

fd.close();
fs.close();
于 2015-05-28T05:43:36.173 回答