Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Оптимальный метод копирования


Автор: BpIstorick 8.7.2006, 00:21
какой метод копирования лучше, то есть - быстрее идет, а так же меньше нагрузка на проц

Методы которые знаю smile

- BlockRead, BlockWrite
- SHFileOperation
- CopyFile
- потоковое копирование (но его фигова знаюsmile )

какой из них приоритетен!, если есть что добавить то пжалуйста smile
Какой из них вообще возможно реализовать с прогрессБаром (собственно ручно сделанным, а не виндовским)

 smile 
 

Автор: Alexeis 8.7.2006, 00:43
Цитата(BpIstorick @  8.7.2006,  00:21 Найти цитируемый пост)
если есть что добавить то пжалуйста

Еще есть файлы отображаемые в память.

Цитата(BpIstorick @  8.7.2006,  00:21 Найти цитируемый пост)
какой метод копирования лучше, то есть - быстрее идет

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

Добавлено @ 00:45 
Цитата(BpIstorick @  8.7.2006,  00:21 Найти цитируемый пост)
 реализовать с прогрессБаром

Да любой если переписывать не файл целиком, а по частям.

Добавлено @ 00:49 
Для быстрого переписывания больших файлов (музыки, фильмов) с одного логического диска на другой желательно использовать большой буфер. Я один раз ради эксперимента написал такую програмку, так она работала В 2,5 РАЗА БЫСТРЕЕ чем копирование ч/з explorer и использовала буфер в 50МБ.  

Автор: Poseidon 8.7.2006, 01:19
Цитата(alexeis1 @  8.7.2006,  00:43 Найти цитируемый пост)
И еще если файл копируется в пределах диска, то самое быстрое movefile
 Сам хоть понял в чем ошибся?

BpIstorick, Используй BlockRead, BlockWrite. Там и буфер можно указать (о катором говорит alexeis1) и прогрессбар пределать и вообще любой контроль осуществить.


Цитата(BpIstorick @  8.7.2006,  00:21 Найти цитируемый пост)
- потоковое копирование (но его фигова знаю )

Вот те пример:
Код
Procedure FileCopy(Const SourceFileName, TargetFileName: String); 
Var 
  S,T   : TFileStream; 
Begin 
 S := TFileStream.Create(sourcefilename, fmOpenRead ); 
 try 
  T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate); 
  try 
    T.CopyFrom(S, S.Size) ; 
    FileSetDate(T.Handle, FileGetDate(S.Handle)); 
  finally 
   T.Free; 
  end; 
 finally 
  S.Free; 
 end; 
end; 


Кстати, еще можно копировать методом LZExpand и матодом Windows. smile
 

Автор: Alexeis 8.7.2006, 01:54
Цитата(Poseidon @  8.7.2006,  01:19 Найти цитируемый пост)
 Сам хоть понял в чем ошибся?

Мда  smile глупость еще та вышла - сейчас поправлю... 

Автор: BpIstorick 8.7.2006, 07:05
Вопрос возник в принципе после прочтения большого количества подобных тем форума smile каждый заморачивается тем, что знает smile я хочу знать чуть больше чем один два метода smile

Ситуация:
два случая

- с логического на логический
- на сетевой диск


Вопрос!

При использовании BlockRead, BlockWrite наблюдал огромную нагрузку на проц! а это не есть ГУД smile
Потом нашел строчку что 3*4*4096 of Byte есть оптимальный буффер, а вообще зависимость какая? больше буффер -> больше нагрузка на ХАРД, или здесь нелинейная???

и какия хитрости?

p.s. В этом методе я разобрался лучше всего smile потому про него спрашиваю, но могу изучить и другие... вот стоит срочно изучать файловые потоки или нет???, но это вопрос на засыпку, необязателен smile 

Автор: Alexeis 8.7.2006, 14:45
Цитата(BpIstorick @  8.7.2006,  07:05 Найти цитируемый пост)
срочно изучать файловые потоки или нет???
Стоит потому что они позволяют копировать файлы более 4Гб.

Добавлено @ 14:56 
Цитата(BpIstorick @  8.7.2006,  07:05 Найти цитируемый пост)
При использовании BlockRead, BlockWrite наблюдал огромную нагрузку на проц!
 Вероятно это не так, просто операция происходит длинельное время во время которого программа не выполняется поскольку ждет завершения работы функции. Процессор просто ждет винт, если сделать второй поток в программе, и возложить но него эту работу то таких проблем не будет (правда будут другие smile ). 
Цитата(BpIstorick @  8.7.2006,  07:05 Найти цитируемый пост)
, а вообще зависимость какая? больше буффер -> больше нагрузка на ХАРД, или здесь нелинейная???
 фокус в том что последовательное считывание кластеров, намного быстрее случайного, если головка винта почти не перемещается(не скачет), то передача данных сильно ускоряется. Вообще желательно использовать буфер на 2-3Мб, т.е. на размер кэша финта, но больший размер все равно ускорит копирование, но при этом будет набльдаться некоторое торможение системы, т.к. Операции с винтом имеют высокий приоритет, да и другие програмы не прочь поработать сами с винтом, WinXp, тот вообще часто к подкачке обращается, независимо хватает ему ОЗУ или нет. 

Автор: BpIstorick 10.7.2006, 00:17
Спасибо всем за разъяснения smile буду разбираться дальше в делфе smile 

Автор: BUGOR 10.7.2006, 09:40
А почему про API ни слова? Мой опыт показывает, что файлы размером не больше 50 мб быстрее всего обрабатываются с помощью  MMF(Memory Mapped Files), даже на 256 метрах памяти, ибо идёт проекция на память, а работа с оперативкой само собой намного быстрее работы с хардом, но файлы большего размера я советую копировать с помощью Read/WriteFile и при этом буфер брать размером не 50 метров, а 64 Кб. 

Автор: Alexeis 10.7.2006, 09:46
BUGOR, 
Цитата(alexeis1 @  8.7.2006,  00:43 Найти цитируемый пост)
Еще есть файлы отображаемые в память.

 

Автор: Akella 10.7.2006, 09:57
Цитата(BpIstorick @  8.7.2006,  07:05 Найти цитируемый пост)
Ситуация:
два случая

- с логического на логический
- на сетевой диск


с использую CopyFile - Винда сама копирует, и я не думаю, под какой версией работает моя прога, и не думаю, какого размера будет файл и какой размер буфера мне ставить. 

Автор: BpIstorick 10.7.2006, 14:54
Цитата(BUGOR @ 10.7.2006,  09:40)
но файлы большего размера я советую копировать с помощью Read/WriteFile и при этом буфер брать размером не 50 метров, а 64 Кб.

А от чего вообще буфер высчитывается? от личного "хочу" или есть параметры к которым он привязывается smile?? ведь это не четкий ответ - "Поверь так лучше":) ПОЧЕМУ?

Попробовал установить буфер размером 

Код

const
  BufSize=2*512*1024;
var
  buffer: array [1..BufSize] of byte;


выдается сообщение "Stack Overflow" (как я понимаю это в переводе - стек перегружен...)!

необходимо получается выделять отдельно память??? или в чем моя ошибка???

p.s. во вложении проект в котором ошибка! проект чисто для разбора с матерьялом созданsmile поэтому неряшлив 

Автор: Matematik 10.7.2006, 15:00
Цитата(BpIstorick @  10.7.2006,  15:54 Найти цитируемый пост)
выдается сообщение "Stack Overflow" (как я понимаю это в переводе - стек перегружен...)!


Динамическое выделение

Код

var
 p:Pointer;
begin
p:=AllocMem(BufSize)
{...}
FreeMem(p)
end
 

Автор: Alexeis 10.7.2006, 17:15
Цитата(BpIstorick @  10.7.2006,  14:54 Найти цитируемый пост)
ак я понимаю это в переводе - стек перегружен...)!

точнее переполнен, это возникает либо при неправельной рекурсии, либо при обилии локальных данных!

Добавлено @ 17:19 
Цитата(Matematik @  10.7.2006,  15:00 Найти цитируемый пост)
Динамическое выделение

Динамическая память выделяется в куче, а не в стеке. 
Непойму к чему 
Цитата(Matematik @  10.7.2006,  15:00 Найти цитируемый пост)
var p:Pointer;beginp:=AllocMem(BufSize){...}FreeMem(p)end


Добавлено @ 17:22 
Конечно же!
Цитата(BpIstorick @  10.7.2006,  14:54 Найти цитируемый пост)

var  
  buffer: array [1..BufSize] of byte;

 вот где собака зарыта!
Надо было делать динамический массив!

Matematik, sorry, теперь понял о чем шла речь с p:=AllocMem(BufSize)    

Автор: BpIstorick 10.7.2006, 20:55
Цитата(alexeis1 @  10.7.2006,  17:15 Найти цитируемый пост)
вот где собака зарыта!
Надо было делать динамический массив!


несколько раз вчитывался и вдумывался, но так и не понял в чем моя ошибка и где зарыта собака! 

1. если я буду использовать динамический массив, то все получится???
2. если буду динамически создавать буффер в виде выделенной памяти, то тоже все получится???

а чем мой статический массив не подошел??? в чем загвоздка???

p.s. и все равно никто не ответил! почему 64к или 48к буфер должен быть? из-за разрядности и доступа к памяти проще процессору обращаться(мои размышления)??? или все таки просто нужно поверить этому и забить smile 

Автор: Alexeis 11.7.2006, 00:20
Цитата(BpIstorick @  10.7.2006,  20:55 Найти цитируемый пост)
1. если я буду использовать динамический массив, то все получится???2. если буду динамически создавать буффер в виде выделенной памяти, то тоже все получится???

И то и другое ВЕРНО! smile 

Цитата(BpIstorick @  10.7.2006,  20:55 Найти цитируемый пост)
а чем мой статический массив не подошел??? в чем загвоздка???

Он жрет память из стека, вот стек и закончился
Код

const
  BufSize=2*512*1024;

это же целый мегабайт - размер всего стека, плюс прога еще расходует на внутренние цели, вот и закончился стек - stack overflow!

Цитата(alexeis1 @  10.7.2006,  17:15 Найти цитируемый пост)
Динамическая память выделяется в куче, а не в стеке. 


Цитата(BpIstorick @  10.7.2006,  20:55 Найти цитируемый пост)
 почему 64к или 48к буфер должен быть?

Глупости, зависит от устройства передачи и приема! Для HDD обычно берут 2Mb
 

Автор: BpIstorick 11.7.2006, 08:17
Попробовал оба способа:
1. динамическое выделение памяти
2. С помощью динамического массива

пришел к выводу что лучше статического массива ничего не придумать smile

скорость в первых двух случаях получалась почему-то вообще мизерной (50-150 kb), а при помощи статического массива достигала реальных 10 и более мегабайт в секунду smile

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

почитать подскажите где smile 

Автор: Alexeis 11.7.2006, 09:22
Цитата(BpIstorick @  11.7.2006,  08:17 Найти цитируемый пост)
скорость в первых двух случаях получалась почему-то вообще мизерной (50-150 kb), а при помощи статического массива достигала реальных 10 и более мегабайт в секунду

У меня при помощи динамической памати получалось 14Мбайт в секунду c логического на логический! на Segate ATA100 80Гб, а с Segate ATA100 80Гб на Segate ATA100 200Гб вообще 25 Мбайт в секунду!
Цитата(BpIstorick @  11.7.2006,  08:17 Найти цитируемый пост)
так же пришел к выводу, что нужно разбираться со структурой самой программы для должного понимания

Выкладывайте код процедуры мы поможем разобраться!  

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