Медленное копирование с диска на дискетту и обратно
Вместо чтения байта за байтом, вы должны открыть файл с размером записи, равным 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]