Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt4] QFile::copy


Автор: mosg 19.8.2009, 12:15
Добрый день.

Проблема: необходимо скопировать большое кол-во файлов через QFile::copy(fromFileName, toFileName) и после этого сразу сжать все эти файлы в архив (все делается в одном коде). Эти действия выполняются последовательно, и по идее должно все работать, но на деле получается, что файлы копируются с запозданием и в архив часть файлов не поподает. Если поставить между действиями копировать и архивировать вывод какого-нить QMessabeBox'а, то все файлы "успевают" скопироваться, а следовательно, попасть в архив.

Может быть кто встречался с такой проблемой, а то не хочется тайменги выставлять или контролировать копирование файлов?

Спасибо.

Автор: ecspertiza 19.8.2009, 13:54
Контроль полюбому необходим, а то это как то неправильно получается мы не знаем есть файл или нет и пытаемся его архивировать.


Автор: mosg 19.8.2009, 14:17
Цитата(ecspertiza @ 19.8.2009,  13:54)
Контроль полюбому необходим, а то это как то неправильно получается мы не знаем есть файл или нет и пытаемся его архивировать.

У меня задача в 100%-ности копирования файлов не стоит, поэтому я и надеюсь отделаться малой кровью. smile Т.е. если из 1000 файлов 2-3х не будет, то это ещё ничего страшного, а вот когда я копирую 1-3 файла, и потом хочу их заархивировать, вот тогда пустой архив "выглядит" не очень радостно.

На мой взгляд, тут дело в том, что процессы копирования происходят путем создания дополнительных потоков для ускорения работы: т.е. у меня к примеру копируется 10 файлов путем:

Код
for (int i = 0; i < files.count(); i++) {
    if (!QFile::copy(fromList.at(i), toList.at(i))) {
        // ошибка
    }
}

acrhive();


Пути абсолютные. Путем Qt создаются 10 потоков, они начинают свое выполнение, часть файлов копируется, а вот часть не успевает, так как сразу подключается ф-ция архивирования acrhive(). В итоге получается неполный или, вообще, пустой архив.

На мой взгляд, должно быть средство, которое отключает данную "фитчу"... 

Автор: andrew_121 19.8.2009, 15:34
т.е. вы думаете что функция копирования асинхронная?
или копирование и архивирование у вас в разных потоках?

Автор: mosg 19.8.2009, 15:55
Цитата(andrew_121 @ 19.8.2009,  15:34)
т.е. вы думаете что функция копирования асинхронная?
или копирование и архивирование у вас в разных потоках?

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

Объясню почему сделал поток (QThead простейший): надо было при архивировании показывать хотя бы как-то, что программа работает и не повисла, поэтому вкрутил симпотичный анимированный GIF (дешево, сердито и красиво smile ) + отдельно работала скрутка файлов в архив, а так, если не пользоваться потоками, то GUI часть подвисала, что и не давало показывать анимацию загрузки... 

Я дополнительно ещё проверил: файлы полностью переносятся в нужную папку перед архивацией, да вот только то ли что-то блокирует их, то ли ещё что-то, но файлы упорно не хотят "лезть" в архив. 

Причем: у меня программа работает в 2-х режимах - GUI и консольный(программа запускается с параметром, и без участия юзера делает тот же архив). Т.е. В GUI пользователь нажимает на кнопочку и все получается, а вот в консольном режиме теже действия не проходят...


зы: понимаю что вопросы задаю мыльные, но код постить не буду, потому как его много, а толку будет думаю мало от этого, ключевые моменты описал smile

Автор: andrew_121 19.8.2009, 17:02
Есть такой вариант. Ради эксперимента.

Если функция "copy()" вернула истину, в потоке, в цикле проверяй условие "QFile::exists()", пока не вернет истину, потом уже добавляй в архив. Возможно скорость немного снизится.

Автор: mosg 20.8.2009, 11:56
Спасибо за предложения, но все таки собака была зарыта в другом месте: так как приложение в консольном режиме (т.е. запуск и завершение отрабатываются самой программой), то после того, как она копировала файлы в папку и начинала в отдельном потоке делать архив, программа успевала закрыться, а при закрытии у меня стоит ф-ция чистки всех временных файлов - что и приводило к созданию пустых архивов. 

Решение: программу закрывать только после завершения выполнения потока!  smile 

Автор: andrew_121 20.8.2009, 19:08
Цитата(mosg @  20.8.2009,  11:56 Найти цитируемый пост)
так как приложение в консольном режиме (т.е. запуск и завершение отрабатываются самой программой), то после того, как она копировала файлы в папку и начинала в отдельном потоке делать архив, программа успевала закрыться, а при закрытии у меня стоит ф-ция чистки всех временных файлов - что и приводило к созданию пустых архивов. 

Так это же очевидно. Для этого потоки и существуют.

Цитата(mosg @  20.8.2009,  11:56 Найти цитируемый пост)
Решение: программу закрывать только после завершения выполнения потока!

Как реализовал?


Автор: mosg 21.8.2009, 17:12
Цитата(andrew_121 @  20.8.2009,  19:08 Найти цитируемый пост)
Так это же очевидно.
Ну да. Тормознул. Бывает такое, редко.  smile 

Цитата(andrew_121 @  20.8.2009,  19:08 Найти цитируемый пост)
Как реализовал?
В основном диалоге, при отработке события завершения работы потока finished() вызывается ф-ция:

Код
connect(thread, SIGNAL(finished()), this, SLOT(on_thread_finished()));


Код
void    CMainDialog::on_thread_finished() {
    // ...
    if (conf->isConsole)
        this->close();
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)