Копирование файлов

В данной статье показаны некоторые методы копирования файлов. Существуют и готовые функции - 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 Мб. Конечно, говорить о правильности результатов можно с трудом, ведь жёсткий диск работает по-разному - иногда быстрее, а иногда медленее.

Кажется, название функции FastFileCopy вполне оправдано. Впрочем, судить о том, какая из функций действительно работает быстрее, нужно по результатам экспериментов на большом числе компьютеров с разными конфигурациями. Но цель данной статьи была не выявить самый быстрый способ, а просто показать об этих способах. Использовать можно любой из методов, все они работоспособны.
Теги:
Копирование
Добавлено: 02 Августа 2018 08:10:49 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...