Отключение буферизации файлового копирования с помощью Qt - PullRequest
0 голосов
/ 02 мая 2018

Я пишу программное обеспечение для резервного копирования данных репликатора файлов с использованием инфраструктуры Qt и испытываю «изъян» при копировании данных.

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

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

Есть ли способ обойти это с помощью Qt? Я пытался использовать QFile::flush(), но это не помогло.

У нас есть FlushFileBuffers из API Win32, но в документации сказано, что он неэффективен при использовании после каждой записи на устройство с диском, когда много операций записи выполняются отдельно.

Мы можем вызвать функцию CreateFile с флагами FILE_FLAG_NO_BUFFERING и FILE_FLAG_WRITE_THROUGH, но есть ли способ сделать это с помощью 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);
}

1 Ответ

0 голосов
/ 05 мая 2018

Для эффективного копирования файлов в Windows вы должны использовать CopyFileEx, а не QFile. CopyFileEx будет использовать API более низкого уровня, что может привести к копированию без копирования на современном оборудовании. Смотрите этот пример CopyFileEx интеграции с Qt .

Чтобы получить нативный HANDLE от QFileDevice (то есть QFile / QSaveFile) и использовать ReOpenFile на QFile, см. этот ответ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...