Russian Qt Forum
Ноябрь 25, 2024, 11:48 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Отображение прогресса копирования файла  (Прочитано 10634 раз)
FluffyMan2000
Гость
« : Октябрь 06, 2012, 20:58 »

Доброго времени суток. Стоит задача отображать прогресс копирования файла. QFile::copy() такой возможности не дает (или возможно все же из QFile::copy() узнать сколько в данный момент скопировано байт?), поэтому решил использовать такую конструкцию:

Код:
QFile sourceFile(source);
QFile destFile(destination);

sourceFile.open(QIODevice::ReadOnly);
destFile.open(QIODevice::WriteOnly);

qint64 size = sourceFile.size();

for (qint64 i = 0; i < size; i += 1024)
{
    destFile.write(sourceFile.read(i));
    sourceFile.seek(i);
    destFile.seek(i);

    qDebug() << (i * 100) / size << "%";
}

но есть две проблемы:
1) эта функция работает очень медленно
2) эта функция вылетает с ошибкой если:
- исходный файл весит меньше 1024 байт (не всегда вылетает)
- исходный файл весит больше 1024 байт, но в конце при копировании считывается порция 1024 байт из файла, но в нем реально осталось меньше, например. тогда он дописывается и вылетает программа с ошибкой.

Подскажите как решить эти проблемы.
Записан
V1KT0P
Гость
« Ответ #1 : Октябрь 06, 2012, 21:05 »

О боже по 1 килобайту копировать, это просто жесть. Копируй хотя-бы по 10 метров( 10485760 байт ). Если следующий кусок меньше 10 метров, то копируй столько сколько есть.
Записан
FluffyMan2000
Гость
« Ответ #2 : Октябрь 06, 2012, 22:18 »

Как это алгоритмически сделать? берем остаток от деления размера файла на 10485760. Получили сколько раз копировать из исходного файла в файл назначения. А остаток - порция, которую дописать в конечный файл единоразово? Или как?
Записан
V1KT0P
Гость
« Ответ #3 : Октябрь 06, 2012, 22:26 »

Как это алгоритмически сделать? берем остаток от деления размера файла на 10485760. Получили сколько раз копировать из исходного файла в файл назначения. А остаток - порция, которую дописать в конечный файл единоразово? Или как?
Да, но идеально будет если сделаешь два потока. Первый читает, второй пишет. Но первый должен следить и не особо спешить если второй не успевает записать. Для этого лучше организовать два буфера, тогда это будет выглядеть так:
Первый считывает кусок в первый буфер, сигнализирует второму потоку и считывает во второй буфер. Второй поток записывает из первого буфера. По окончании сигнализирует первому, который меняет указатели на буферы и оповещает второй поток и тут-же считывает во второй буфер и так пока не скопируется весь файл. И советую не привязываться к определенной длине блока, если второй поток простаивает, то стоит увеличить размер блока.
Записан
FluffyMan2000
Гость
« Ответ #4 : Октябрь 06, 2012, 23:00 »

Сложновато с потоками. У меня процесс копирования уже в отдельном потоке идёт и нужно всего лишь прогресс отображать. Завтра попробую и отпишусь.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #5 : Октябрь 06, 2012, 23:05 »

Почему вы решили заняться Qt, когда не можете написать настолько простой алгоритм, который дают студентам первого курса для разминки?
Записан
FluffyMan2000
Гость
« Ответ #6 : Октябрь 06, 2012, 23:28 »

Очень помог Ваш комментарий при решении задачи
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #7 : Октябрь 06, 2012, 23:35 »

Очень помог Ваш комментарий при решении задачи

такие задачи нужно решать упорным трудом, раз за разом пытаясь ЛОГИЧЕСКИ понять и написать код, который будет работать. Никто вам в этом не поможет, либо вы сами себя сломаете, либо будете по любой мелочной причине бежать на форум. Ваша задача никакого отношения к Qt не имеет, это алгоритм на три строки для начинающих изучать Си и цикл while. Если вы хотите стать разработчиком - забудьте о форумах на полгода. Целиком и полностью.
Записан
FluffyMan2000
Гость
« Ответ #8 : Октябрь 07, 2012, 09:03 »

Отчасти с Вами согласен. Однако с qt это связано. При чтении документации на класс QIODevice и его метод ::read(qint64 maxSize) я выяснил, что он возвращает реально считанное количество байт. Поэтому в цикле while можно читать и писать порциями не беспокоясь, что считается или запишется лишние байты с порции. Попробую и скажу вышло или нет.

А про то, что только самостоятельное решение задач может помочь абсолютно согласен.
Записан
mutineer
Гость
« Ответ #9 : Октябрь 07, 2012, 09:30 »

А зачем ты на каждой итерации делаешь seek ?
Записан
FluffyMan2000
Гость
« Ответ #10 : Октябрь 07, 2012, 09:45 »

А зачем ты на каждой итерации делаешь seek ?

перемещаю позицию курсора на новую порцию для считывания
Записан
mutineer
Гость
« Ответ #11 : Октябрь 07, 2012, 10:03 »

А зачем ты на каждой итерации делаешь seek ?

перемещаю позицию курсора на новую порцию для считывания

Курсор сам смещается при каждом чтении/записи, а ты его на каждой итерации двигаешь назад и переписываешь одни и те же данные по несколько раз
Записан
FluffyMan2000
Гость
« Ответ #12 : Октябрь 07, 2012, 10:19 »

А зачем ты на каждой итерации делаешь seek ?

перемещаю позицию курсора на новую порцию для считывания

Курсор сам смещается при каждом чтении/записи, а ты его на каждой итерации двигаешь назад и переписываешь одни и те же данные по несколько раз

понял. Вот этот код работает:
Код:
   
dest.open(QIODevice::WriteOnly);
file.open(QIODevice::ReadOnly);

QByteArray buf = 0;
qint64 progres = 0;
while (!(buf = file.read(1048576)).isEmpty())
{
     dest.write(buf);
     progres += buf.size();
     qDebug() << (double)((progres * 100) / file.size()) << "%";
}

но программа выдает ошибку если ее закрыть. в чем проблема может быть (файлы закрываются) ?
« Последнее редактирование: Октябрь 07, 2012, 10:22 от FluffyMan2000 » Записан
mutineer
Гость
« Ответ #13 : Октябрь 07, 2012, 10:22 »

А ошибка в этом мире только одна бывает, что ты так скромно умалчиваешь о ее типе?
Записан
FluffyMan2000
Гость
« Ответ #14 : Октябрь 07, 2012, 10:36 »

А ошибка в этом мире только одна бывает, что ты так скромно умалчиваешь о ее типе?

на консоль выдается сообщение
Код:
Программа неожиданно завершилась.
D:\Путь_к_файлу\FileOperator-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK_______\release\FileOperator.exe завершился с кодом -1073741819

и выскакивает стандартное окно ОС http://rghost.ru/40788568.view
« Последнее редактирование: Октябрь 07, 2012, 10:46 от FluffyMan2000 » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.129 секунд. Запросов: 23.