Копирование содержимого QFile в другой QFile, каков оптимальный путь?

Мне нужно скопировать 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, я думаю, что ответ должен быть общим для любого API файлового ввода-вывода, который поддерживает отображение памяти.

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. Такие функции, как сопоставление памяти, имеют тенденцию действовать по-разному на разных платформах, например, максимальный размер файла, который вы отображаете в памяти, может быть разным.

То, что является оптимальным методом, всегда немного в глазах смотрящего. Вот как минимум один работающий более короткий метод:

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

И отображение памяти... Я стараюсь держаться подальше от таких вещей. Я никогда не уверен, насколько они независимы от платформы.

Используйте этот метод 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();
Другие вопросы по тегам