Советы по Delphi


Медленное копирование с диска на дискетту и обратно


Вместо чтения байта за байтом, вы должны открыть файл с размером записи, равным 64K или около того, и читать блоками. Это ускорит операцию. Если вам необходимо это сделать очень быстро и без особых затрат на программирование, поищите свободнораспространяемые компоненты для копирования файлов....

Пример процедуры копирования файла copyfile:

    Function CopyFile(FromPath,ToPath : String) : integer;
Var F1          : file; F2          : file; NumRead     : word;

NumWritten  : word; Buf         : pointer; BufSize     : longint; Totalbytes  : longint; TotalRead   : longint;
Begin Result := 0; Assignfile(f1,FromPath); Assignfile(F2,ToPath); reset(F1,1); TotalBytes := Filesize(F1); Rewrite(F2,1); BufSize := 16384; GetMem(buf,BufSize); TotalRead :=0; repeat BlockRead(F1, Buf^, BufSize, NumRead); inc(TotalRead,NumRead); BlockWrite(F2, Buf^, NumRead, NumWritten); until (NumRead = 0) or (NumWritten <> NumRead); if (NumWritten <> NumRead) then begin {ошибка } result := -1; end closefile(f1); Closefile(f2); End;

Если у вас есть file of byte (бинарный файл), или просто File, вы должны использовать Blockread, который позволяет устанавливать размер буфера, равный 64Кб. Ниже я предоставляю вашему вниманию "быстрый" способ достижения цели. Воспользуйтесь Compress (который, я надеюсь, вы найдете в поставке Delphi, в противном случае обратитесь на сайт Microsoft), который позволит вам создавать файлы типа filename.ex_. Это означает, что для копирования информации требуется гораздо меньше усилий.

Ниже приведен некоторый код, позволяющий копировать файлы. Будет даже лучше, если файлы будут в их текущем состоянии, поскольку, если они сжатые, процедура их просто не скопирует!

    function TInstallForm.UnCompress(src, dest: String; Var Error : LongInt):
Boolean;
var
s, d: TOFStruct; fs, fd: Integer; fnSrc, fnDest: PChar; begin
src:=src + #0; dest:=dest + #0; fnSrc:=@src[1];   { Хитро преобразуем строки в ASCIIZ } fnDest:=@dest[1];
fs := LZOpenFile(fnSrc, s, OF_READ);    { Получаем дескриптор файла } fd := LZOpenFile(fnDest, d, OF_CREATE);
Error:=LZCopy(fs, fd);           { Вот магический вызов API } Result:=(Error > -1);
LZClose( fs );    { Убедитесь, что закрыли! } LZClose( fd ); end;

Procedure UnCompressError(Error : LongInt);
Begin
Case
Error Of LZERROR_BADINHANDLE : S:='Неверный дескриптор исходного файла'; LZERROR_BADOUTHANDLE: S:='Неверный дескриптор целевого файла'; LZERROR_BADVALUE    : S:='Входной параметр вышел за границы диапазона'; LZERROR_GLOBALLOC   : S:='Недостаточно памяти для требуемого буфера'; LZERROR_GLOBLOCK    : S:='Неверный дескриптор структуры внутренних данных'; LZERROR_READ        : S:='Неверный формат исходного файла'; LZERROR_UNKNOWNALG  : S:='Исходный файл был упакован с использованием неизвестного алгоритма сжатия'; LZERROR_WRITE       : S:='Недостаточно места для выходного файла' Else S:='Неизвестная проблема с распаковкой' End; MessageDlg(S, mtConfirmation,[mbOK],0); Close End;

    function CopyFile( SrcName,DestName : string ): boolean;
{ базовый метод копирования файла; требует полный путь & имя для исходного & целевого файла } var
Buf: array[1..1024*4] of byte;   { этот размер может быть изменен.. объявляя указатель, вы можете использовать GetMem для создания в куче большого буфера }
TotalRead: longint; NumRead, NumWritten: word; TotalWritten: longint; FromFileSize: longint; FrF,ToF :    file; FileTime :    longint; begin

FGetTime(SrcName,FileTime); Assign(FrF,SrcName); Reset(FrF,1); FromFileSize := FileSize(FrF);
Assign(ToF,DestName); Rewrite(ToF,1); TotalRead := 0; TotalWritten := 0; REPEAT BlockRead (FrF, Buf, SizeOf(Buf), NumRead); TotalRead := TotalRead + NumRead;
BlockWrite(ToF, Buf, NumRead, NumWritten); TotalWritten := TotalWritten + NumWritten; UNTIL (NumRead = 0) OR (NumWritten <> NumRead); Close(FrF); Close(ToF); { возвращаем true, если они равны, в противном случае возвращаем false } CopyFile := (TotalWritten = FromFileSize); end;

[001713]



Содержание раздела