2

QFileaを別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;
    }
}

このフラグメントからは明らかではありませんが、大きなファイルの進行状況のコールバックとキャンセル機能を提供できるように、バイナリ ファイル全体をチャンク単位で別の場所にコピーするだけです。

もう 1 つのアイデアは、メモリ マッピングを使用することです。するべきか?その場合、ソース ファイルのみをマップして を使用するか_destFile.write、両方をマップして を使用する必要がありますmemcpyか?

この質問は実際には Qt に結び付けられていないと思います。答えは、メモリ マッピングをサポートするすべてのファイル I/O API に共通するはずです。

4

3 に答える 3

3

わかりました、わかりました、それがメモリ マッピング ソリューションでなければなりません。これが1つです:

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();

これにより、宛先ファイルのみがメモリにマップされます。ソースファイルもマップすることで大きな違いが生じるとは思えません。しかし、これは具体的な測定のためのものであり、仮定ではありません。

もう 1 つの問題は、ファイル全体を一度にメモリにマップできるかどうかです。常にマッピングを解除して再マッピングすると、確かにパフォーマンスが低下します。また、Qt を使用している場合でも。メモリ マッピングのような関数は、異なるプラットフォームでは驚くほど異なる動作をする傾向があります。たとえば、メモリにマップする最大ファイル サイズが異なる場合があります。

于 2013-08-18T17:58:02.273 に答える
1

最適な方法が何であるかは、見る人の目の中に常に少しあります。少なくとも 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 に答える