Форум программистов, компьютерный форум, киберфорум
C++/CLI Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67

Прогресс выполнения копирования через File::Copy или быстрое копирование

23.10.2018, 04:27. Показов 3003. Ответов 36

Студворк — интернет-сервис помощи студентам
Доброго времени суток, коллеги.
Я конечно не могу похвастаться большим опытом в программировании на С++, тем более что приходиться работать в среде с /clr
Задача простая, скопировать файлы и попутно выводить прогресс. Среди условий копирование файлов с компа на "флешку" (на самом деле устройство определяемое как флешка) и обратно.
Если при копирование НА комп с носителя все прошло благополучно, и файлы копируются, и прогресс показывается и скорость удовлетворительная, то при обратной операции, (Внимание!!!) те же файлы, на то же устройство, в общем полностью обратный процесс, занимает очень и очень длительное время. В чем причина не понятно, подозреваю, что эта проблема вызвана самим устройством (флешкой), то есть подозреваю что аппаратно чтение быстрее скорости априори и при использовании моей функции для копирования, происходит многократное усугубление ситуации.
Также, не будь дураком, порыскал в гугле на тему как ускорить копирование, так и не разобравшись, догадался использовать:
C++
1
System::IO::File::Copy("источник", "назначение")
оказалось что эта функция работает в направлении С компа НА флешку куда быстрее. Тут понятно, по этой теме инфы предостаточно виноваты во всем потоковые операции. Я решил не заморачиваться, и быстренько состряпал функцию для вывода процесса копирования с использование наиболее быстрого имеющегося у меня кода, однако вот уже битый час не могу понять почему функция, которая должна складывать размер файлов и выдавать результат сразу выдает конечный размер файла, как только до него доходит очередь.
То есть функция складывает размер файлов и выдает результат, но выдает не совсем так как ожидалось. Я уже эту функцию перевернул с ног на голову и как только не извращался, даже дошел до того что брал под контроль папки и считывал размер всех ее файлов, но она упрямо выдает сразу конечный результат, когда четко известно что копирование еще не завершено.
Может мне кто-то помочь в данной ситуации. Самый простой вариант это довести до ума функцию сообщающую прогресс копирования при использовании
C++
1
File::Copy();
, ну или может вы поделитесь своим рабочим кодом быстрого копирования файлов с прогрессом.
Для справки, проект не коммерческий, даже немного благотворительный ))

Привожу для примера один из вариантов функции отслеживающей прогресс, как бы отслеживающей ((
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int checkSumm(ArrayList^ commands){
            int allSumm = 0;
            int checkedSumm = 0;
            int result = 0;
            String^ patternCopy = "^copy_\\((.+)\\)_to_\\((.+)\\)$";
            for each(String^ commanda in commands){
                if(Regex::IsMatch(commanda,patternCopy)){
                    MatchCollection^ matching = Regex::Matches(commanda,patternCopy);
                    String^ fileFrom = (String^) matching->default[0]->Groups[1]->Value;
                    String^ fileTo = (String^) matching->default[0]->Groups[2]->Value;
                    arrOutFiles->Add(fileTo);
                    FileInfo^ finfoFrom = gcnew FileInfo(fileFrom);
                    FileInfo^ finfoTo = gcnew FileInfo(fileTo);
                    allSumm += Convert::ToInt32(finfoFrom->Length);
                    if(finfoTo->Exists){
                        checkedSumm += Convert::ToInt32(finfoTo->Length);
                    }
                }
            }
//на этого крокодила ниже не обращайте внимания, мне так надо )))
            result = Convert::ToInt32(Math::Floor((double)checkedSumm*(double)100/(double)allSumm));
            return result;
}

Добавлено через 14 минут
Небольшое дополнение: Есть мысли, что функция копирования создает "пустой" файл конечного объема, отсюда возможно что моя функция прогресса получает такой результат, но на флешке при прерванной операции фалйы имеют реальный размер, я конечно могу ошибаться и могу еще много чего не знать. Опыта ведь мало (((
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.10.2018, 04:27
Ответы с готовыми решениями:

Отобразить прогресс перемещения или копирования файла (CopyFileEx или MoveFileWithProgress)
Добрый день! Хочу при перемещении файла отображать прогресс, например в ProgressBar. Использую функцию MoveFileWithProgress. Знаю, там...

Файл базы SQLITE не копируется через IO.File.Copy
Ребят, никто не сталкивался? Хочу сделать кнопочку создания (копирования) резервной коаии базы данных. База пока не сильно надулась, всего...

Ожидания выполнения до конца или прогресс бар
Всем привет! Суть в том что при загрузке фотографий в БД , если закрыть окно - то фотографии загружаются не полностью.returnValue - дает...

36
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 06:05
Нужен прогресс - копируйте поток вручную с подсчётом скопированного. Либо пользуйтесь расширенным копированием Windows, с отображением её окна прогресса.
А не то, что вы придумали.
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 11:25  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
копируйте поток вручную с подсчётом скопированного
Я же вроде описал проблему, слишком медленно это, нужна альтернатива.
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 11:52
Я же написал, прогресс так не определить.
Что за устройство или его режим работы? Какого размера файлы?

Добавлено через 7 минут
Покажите код, которым вы копировали файлы по частям, с которыми слишком медленно.
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 13:04  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
Я же написал, прогресс так не определить.
Получается, но с выше оговоренными проблемами
Цитата Сообщение от Rius Посмотреть сообщение
Что за устройство или его режим работы? Какого размера файлы?
Предполагается работа с навигаторами, флешки в данный момент являются эмуляторами этих устройств с записаными на них Rom`ами. Программисты, которые писали аналоги программ, говорят что разницы работы между флешкой и подключенным навигатором нет вообще. Rom используется для полноценного тестирования.
Цитата Сообщение от Rius Посмотреть сообщение
Покажите код, которым вы копировали файлы по частям, с которыми слишком медленно.
Вот:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void copyFiles(ArrayList^ fromFiles, ArrayList^ toFiles){
            Debug::WriteLine("Копируем");
            int lastreport = 0;// разрыв для удаления подвисания из-за частого репорта о состоянии
            int progress = 0;
            int allBytes = GetSizeAllFiles(fromFiles);
            for(int i=0;i<fromFiles->Count; i++){
                this->SetStatusOne("Копирование: "+(String^)fromFiles->default[i]);
                Debug::WriteLine("Копирование: "+(String^)fromFiles->default[i]);
                
                FileStream^ freadstream = File::Open((String^)fromFiles->default[i], FileMode::Open);
                FileStream^ fwritestream = File::Open((String^)toFiles->default[i], FileMode::OpenOrCreate);
                BinaryReader^ binreader = gcnew BinaryReader(freadstream);
                BinaryWriter^ binwriter = gcnew BinaryWriter(fwritestream);
                while(binreader->BaseStream->Position<binreader->BaseStream->Length){
                    int now = Environment::TickCount;
                    array<unsigned char>^ bytes = binreader->ReadBytes(4096);
                    //binwriter->Write(binreader->ReadBytes(4096)); ***** и так пробовал, разницы нет
                    binwriter->Write(bytes);
                    progress += bytes->Length;
                    delete bytes;
                    //если прошло более 100мс сообщаем состояние копирования, без этого программа подвисает
                    if(lastreport+100 < now){
                        this->ReportProgessOne((int)Math::Floor((double)progress*100/(double)allBytes));
                        lastreport = now;
                    }
                }
                binreader->Close();
                binwriter->Close();
                freadstream->Close();
                fwritestream->Close();
            }
            Debug::WriteLine("Копирование завершено");
        }
Добавлено через 4 минуты
Цитата Сообщение от Rius Посмотреть сообщение
Какого размера файлы?
Размер файлов до 100мб, хотя как правило такой 1 остальные поменьше
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 14:01
Цитата Сообщение от PsychoTech Посмотреть сообщение
при обратной операции, (Внимание!!!) те же файлы, на то же устройство, в общем полностью обратный процесс, занимает очень и очень длительное время.
Каков объём файла и какая скорость получается?
Цитата Сообщение от PsychoTech Посмотреть сообщение
Предполагается работа с навигаторами, флешки в данный момент являются эмуляторами этих устройств с записаными на них Rom`ами. Программисты, которые писали аналоги программ, говорят что разницы работы между флешкой и подключенным навигатором нет вообще. Rom используется для полноценного тестирования.
Не понял. Флешка с файлами используется вместо USB накопителя, в котором работает навигатор при подключении к ПК? Файлы прошивки используются вместо каких-то файлов данных?
Цитата Сообщение от PsychoTech Посмотреть сообщение
Вот:
BinaryReader не нужен. Подвисает, если программа оконная, не из-за этого.

Цитата Сообщение от PsychoTech Посмотреть сообщение
Размер файлов до 100мб
Скорее всего Windows за вас буферизует запись, поэтому вам кажется, что готовые функции копируют быстро.

Попробуйте прогу из архива.
Кликните здесь для просмотра всего текста

Файлы обязаны быть кратны 512 байтам.
Windows Batch file
1
copy.exe use-buffer c:\from-file.bin d:\to-file.bin
Windows Batch file
1
copy.exe not-buffer c:\from-file.bin d:\to-file.bin


Цитата Сообщение от PsychoTech Посмотреть сообщение
Я же вроде описал проблему, слишком медленно это, нужна альтернатива.
Ещё я выше говорил, что есть новые виндовые функции копирования с прогрессом: SHFileOperation и IFileOperation.
Вложения
Тип файла: zip copy.zip (7.7 Кб, 7 просмотров)
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 14:41  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
какая скорость получается
Копирование с носителя на комп файл примерно 63мб копируется 10-20сек
обратное копирование занимает 5+ Минут
Цитата Сообщение от Rius Посмотреть сообщение
Не понял. Флешка с файлами используется вместо USB накопителя, в котором работает навигатор при подключении к ПК? Файлы прошивки используются вместо каких-то файлов данных?
Цитата Сообщение от PsychoTech Посмотреть сообщение
Да это не суть, флешка просто эмулирует полностью файловую структуру и некоторые файлы навигатора, это позволит подготовить навигатор для работы и проверить его настройки, никакой активности в этот момент нет ни на эму-флешке, ни на реальном устройстве (оно обычно выключеным подключается).
Цитата Сообщение от Rius Посмотреть сообщение
BinaryReader не нужен.
Сейчас я не понял а как же копировать в бинарном формате
Цитата Сообщение от Rius Посмотреть сообщение
Подвисает, если программа оконная, не из-за этого.
Подвисает, когда backgroundWorker слишком часто рапортует, это проблема устраняется прерыванием рапорта по времени, на это тоже не стоит обращать внимания Работает и есть не просит, пусть работает. Главное что на процесс копирования она не влияет никак.

Цитата Сообщение от Rius Посмотреть сообщение
Скорее всего Windows за вас буферизует запись, поэтому вам кажется, что готовые функции копируют быстро.
Кажется? как бы разница заметна 10-20 секунд или 5 и более МИНУТ.

Программы в архиве нет, собрать нечем.(((

Добавлено через 11 минут
C++
1
2
3
4
5
//ВАриант1
File::Copy((String^)fromFiles->default[i],(String^)toFiles->default[i], true);
//ВАриант2
array<unsigned char>^ bytes = File::ReadAllBytes((String^)fromFiles->default[i]);
File::WriteAllBytes((String^)toFiles->default[i],bytes);
Для справки Вариант 1 и 2 работают практически одинаково подозреваю что вариант 1 построен на варианте 2
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 15:48
Цитата Сообщение от PsychoTech Посмотреть сообщение
Сейчас я не понял а как же копировать в бинарном формате
FileStream и сам по себе умеет работать с массивами байт, как любой Stream.
BinaryReader/BinaryWriter нужен для более типизированных операций, типа чтения/записи чисел указанной разрядности.
Цитата Сообщение от PsychoTech Посмотреть сообщение
Кажется? как бы разница заметна 10-20 секунд или 5 и более МИНУТ.
Да запросто, если флешка совсем фиговая и кеширование включено. 2-й пункт:

Цитата Сообщение от PsychoTech Посмотреть сообщение
Программы в архиве нет, собрать нечем.(((
Я думал, что раз у вас код на C++/CLI, то Visual Studio под рукой есть.
Собрал, в архиве ниже.
Кликните здесь для просмотра всего текста
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Microsoft Windows [Version 10.0.17134.345]
(c) Корпорация Майкрософт (Microsoft Corporation), 2018. Все права защищены.
 
r:\copy\_Output\Debug>copy.exe use-buffer demo.bin demo2.bin
Copying from 'r:\copy\_Output\Debug\demo.bin' to 'r:\copy\_Output\Debug\demo2.bin'...
1024/1024 (100%). Completed.
Completed.
 
r:\copy\_Output\Debug>copy.exe no-buffer demo.bin demo2.bin
Copying from 'r:\copy\_Output\Debug\demo.bin' to 'r:\copy\_Output\Debug\demo2.bin'...
1024/1024 (100%). Completed.
Completed.
 
r:\copy\_Output\Debug>


Цитата Сообщение от PsychoTech Посмотреть сообщение
подозреваю что вариант 1 построен на варианте 2
Ни в коем случае. Нормальные операции копирования не загружают весь файл в ОЗУ.
Но исходники можете посмотреть рефлектором, при желании.
Вложения
Тип файла: zip copy.zip (16.0 Кб, 7 просмотров)
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 15:56
Цитата Сообщение от PsychoTech Посмотреть сообщение
Подвисает, когда backgroundWorker слишком часто рапортует, это проблема устраняется прерыванием рапорта по времени, на это тоже не стоит обращать внимания Работает и есть не просит, пусть работает. Главное что на процесс копирования она не влияет никак.
Ок. Но лучше будет переводить в проценты целочисленные, от 0% до 100%. Потом смотреть, изменилось ли целое число. Если да, рапортовать.
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 16:30  [ТС]
Rius, а для чего вы мне программу эту скинули?
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 16:31
Там можно проверить копирование с кешированием и без. Без оного просто так не запустить.
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 16:35  [ТС]
но что это дает?
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 16:41
Проверьте и сообщите результаты. За сколько секунд скопируется файл.
Только файл должен быть кратен 512 байтам.
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 16:43  [ТС]
результат тот же что и у моей функции с буфером как через
C++
1
 File::Copy()
без буфера также медленно как через мою.
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 16:46
А вот там
Цитата Сообщение от Rius Посмотреть сообщение
2-й пункт:
у вас как настроено?
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 16:47  [ТС]
у меня этого нет
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 16:47
Цитата Сообщение от PsychoTech Посмотреть сообщение
результат тот же что и у моей функции с буфером как через
File::Copy()
без буфера также медленно как через мою.
Т.е. с use-buffer копирует достаточно быстро для вас?
А с no-buffer копирует так же медленно, как у вас в коде -
Цитата Сообщение от PsychoTech Посмотреть сообщение
Вот:
Так?
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 16:48  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
Т.е. с use-buffer копирует достаточно быстро для вас?
А с no-buffer копирует так же медленно, как у вас в коде -
так
0
Эксперт .NET
 Аватар для Rius
13165 / 7725 / 1679
Регистрация: 25.05.2015
Сообщений: 23,535
Записей в блоге: 14
23.10.2018, 16:53
Цитата Сообщение от PsychoTech Посмотреть сообщение
у меня этого нет
Что за Windows-то такая?
Где это искать

Цитата Сообщение от PsychoTech Посмотреть сообщение
так
Но вот, значит, теперь вы можете взять мой код и применить у себя. Для этого исходники в архиве были.
0
12 / 4 / 1
Регистрация: 11.09.2018
Сообщений: 67
23.10.2018, 16:57  [ТС]
Цитата Сообщение от Rius Посмотреть сообщение
Но вот, значит, теперь вы можете взять мой код и применить у себя. Для этого исходники в архиве были.
только вот опыта у меня по такой адаптации нет, если с просто С++ на /cli я еще могу адаптивать, то с шарпа на /cli тут мои навыки уже все )))
может соберете простенькую библиотеку dll, у меня уже одна используется с шарпа работает вроде нормально.
Или быть может перепишите на /cli? Этот вариант более предпочтительней.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.10.2018, 16:57
Помогаю со студенческими работами здесь

Не удаётся отображать прогресс выполнения SQL запросов через Recordset
Возможно, тема уже обсуждалась, но ответа на свой вопрос через поиск не нашёл. Прошу помочь, если кто-то сталкивался с аналогичной...

Fail to copy file to HDD.File:E\images\WOP000280OXXTC0111.SWM
Добрый день,новичек просит помощи в решении ошибки(тема),возникающей при установке W7 домашняя расширенная (лицензионная,пред установлен...

Построчное копирование папок, с сохранением структуры или копирования из файла
Добрый вечер. 1 вопрос: Подскажите пожалуйста, как можно произвести копирование каталогов с определенным вложением (содержимым...

Прогресс выполнения функции AJAX и время выполнения
Здравствуйте. Как ни странно не нашел ответа на решение своей проблемы. Есть функция, которая обрабатывается AJAX-ом на стороне сервера....

Команда копирования Copy
Команда копирования Copy: 1) Добавить несколько строк с клавиатуры в конец существующего текстового файла (txt). 2) Что следует выбрать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru