Я разрабатываю приложение, которое необходимо скопировать много файлов из одной папки в другую, используя QT (5.6.1)QT - QFile операция копирования очень медленно
Для делать это, я был используя метод QFile::copy()
. Это хорошо работает, за исключением одного: это чрезвычайно медленно. Выполняется более чем в два раза больше времени, чем одна операция копирования выполняется с помощью обозревателя Windows.
Удивление, почему это было, я вырыл в исходный код QT, и я нашел это в qfile.cpp
, который выглядит уместным:
char block[4096];
qint64 totalRead = 0;
while(!atEnd()) {
qint64 in = read(block, sizeof(block));
if (in <= 0)
break;
totalRead += in;
if(in != out.write(block, in)) {
close();
d->setError(QFile::CopyError, tr("Failure to write block"));
error = true;
break;
}
}
Таким образом, от того, что я понимаю, операция копирования с помощью 4096- байтовый буфер. Это очень мало для операции копирования и вполне может быть причиной проблемы. Так что я сделал изменить размер буфера:
char block[4194304]; // 4MB buffer
Затем я восстановил всю библиотеку QT, чтобы включить эти изменения. Однако вся модификация полностью нарушила метод. Теперь, когда мое приложение пытается вызвать QFile :: Copy(), операция прерывается немедленно (метод даже не запускается, останавливается перед первой строкой в соответствии с отладчиком QtCreator). Отладчик говорит мне:
The inferior stopped because it received a signal from the Operating System.
Signal name :
SIGSEGV
Signal meaning :
Segmentation fault
Мой C++ немного ржавый, но я не понимаю, как просто изменить размер выделения массива может полностью нарушить способ ... кто может помочь либо:
1) Расскажите, почему QFile: Copy() настолько медленный (я что-то упускаю? Это не только на моем ПК, протестированном на нескольких разных машинах). И действительно ли коллаптик - это код, который я написал выше или что-то еще? 2) Расскажите, почему это одно изменение полностью ломается QFile
В qtbase есть тесты ('тесты/тесты/corelib/io/qfile'), который пытается прочитать файл на Win32 с использованием разных размеров блоков. Я не уверен, почему 4K был универсально выбран. Возможно, это зависит от технологии жесткого диска? Не могли бы вы попробовать запустить тестовый тест ('readBigFile_Win32') и проверить? – peppe
В Windows лучше всего использовать CopyFileEx, см. [Этот полный пример] (http://stackoverflow.com/q/19136936/1329652) с индикатором прогресса :) –