Копирование файлов
Автор: Ерёмин Андрей
Использованы материалы: dmitry9.nm.ru
В данной статье показаны некоторые методы копирования файлов. Существуют и готовые функции - CopyFile(), CopyFileEx(), но порой они неприменимы. Например, при использовании функции CopyFile() с большими файлами мы не имеем доступа к процессу копирования, т.е. программа на некоторое время просто "зависает". Из методов, приведённых ниже, только первый позволяет контроллировать процесс копирования - можно добавить прогресс-индикатор выполнения или отображать объём скопированных данных.
1. Копирование методом Pascal
type TCallBack=procedure (Position,Size: Longint); {Для индикации процесса копирования} procedure FastFileCopy(Const InfileName, OutFileName: String; CallBack: TCallBack); const BufSize = 3*4*4096; { 48Kbytes дает прекрасный результат } type PBuffer = ^TBuffer; TBuffer = array [1..BufSize] of Byte; var Size : integer; Buffer : PBuffer; infile, outfile : File; SizeDone,SizeFile: Longint; begin if (InFileName <> OutFileName) then begin buffer := Nil; AssignFile(infile, InFileName); System.Reset(infile, 1); try SizeFile := FileSize(infile); AssignFile(outfile, OutFileName); System.Rewrite(outfile, 1); try SizeDone := 0; New(Buffer); repeat BlockRead(infile, Buffer^, BufSize, Size); Inc(SizeDone, Size); CallBack(SizeDone, SizeFile); BlockWrite(outfile,Buffer^, Size) until Size < BufSize; FileSetDate(TFileRec(outfile).Handle, FileGetDate(TFileRec(infile).Handle)); finally if Buffer <> Nil then Dispose(Buffer); System.Close(outfile) end; finally System.Close(infile); end; end else Raise EInOutError.Create('File cannot be copied into itself'); end;
2. Копирование методом потока.
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;
3. Копирование методом LZExpand
uses LZExpand; procedure CopyFile(FromFileName, ToFileName : string); var FromFile, ToFile: File; begin AssignFile(FromFile, FromFileName); AssignFile(ToFile, ToFileName); Reset(FromFile); try Rewrite(ToFile); try if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle) < 0 then raise Exception.Create('Error using LZCopy') finally CloseFile(ToFile); end; finally CloseFile(FromFile); end; end;
4. Копирование методами Windows
uses ShellApi; function WindowsCopyFile(FromFile, ToDir : string) : boolean; var F : TShFileOpStruct; begin F.Wnd := 0; F.wFunc := FO_COPY; FromFile:=FromFile+#0; F.pFrom:=pchar(FromFile); ToDir:=ToDir+#0; F.pTo:=pchar(ToDir); F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION; Result:=ShFileOperation(F) = 0; end; // Пример копирования: procedure TForm1.Button1Click(Sender: TObject); begin if not WindowsCopyFile('C:\UTIL\ARJ.EXE', GetCurrentDir) then ShowMessage('Copy Failed'); end;
Мной были сделаны некоторые эксперименты с данными функциями. Во всех случаях копировался один и тот же файл объёмом 122 Мб. Конечно, говорить о правильности результатов можно с трудом, ведь жёсткий диск работает по-разному - иногда быстрее, а иногда медленее. Но в любом случае, результаты есть:
Метод | Опыт 1 (сек.) | Опыт 2 (сек.) | Средняя скорость |
---|---|---|---|
1 |
3.355 |
3.515 |
3.435 |
2 |
4.467 |
4.286 |
4.377 |
3 |
3.545 |
3.395 |
3.470 |
4 |
3.696 |
5.478 |
4.587 |
Кажется, название функции FastFileCopy вполне оправдано. Впрочем, судить о том, какая из функций действительно работает быстрее, нужно по результатам экспериментов на большом числе компьютеров с разными конфигурациями. Но цель данной статьи была не выявить самый быстрый способ, а просто показать об этих способах. Использовать можно любой из методов, все они работоспособны.
Автор: Ерёмин А.А.
Статья добавлена: 16 февраля 2006
Следующая статья: Работа со строковыми типами данных »
Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.
Статьи, похожие по тематике
- Как прочитать ID3-Tag'и из MP3-файла?
- Конвертирование графических форматов
- Написание инсталлятора на Delphi
- Обучающий курс. 25. Работа с файлами и каталогами (часть 1)
- Обход дерева каталогов с прерыванием и возобновлением
- Работа с HTML-справкой в программах
- Работа с реестром и INI-файлами в Delphi
- Работа с форматом M3U
- Скачиваем файлы из интернета
- Сохранение настроек
- Формат файлов RES применительно к BITMAP-ресурсам
Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:
Ссылка для форумов (BBCode):
Быстрая вставка ссылки на статью в сообщениях на сайте:
{{a:19}} (буква a — латинская) — только адрес статьи (URL);
{{статья:19}} — полноценная HTML-ссылка на статью (текст ссылки — название статьи).
Поделитесь ссылкой в социальных сетях:
Комментарии читателей к данной статье
Репутация: +40 |
Ерёмин А.А. (8 января 2012, 23:26): Цитата (нескажу): Подскажите плиз, как делать индикацию в 1 случае? Взять размер файла с помощью FileSize(), ну а дальше понятно, надеюсь. |
Репутация: нет |
нескажу (8 января 2012, 13:27): Подскажите плиз, как делать индикацию в 1 случае?
|
Репутация: +40 |
Ерёмин А.А. (26 апреля 2009, 23:21): А в чём проблема? Не умеем циклы писать? :-)
|
Репутация: нет |
demyan (26 апреля 2009, 17:43): Отлично.
Еще бы про то как 10 файлов скопировать сразу а не один как на примере. |
Оставлять комментарии к статьям могут только зарегистрированные пользователи.