Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Быстрое копирование с диска на дискету и обратно

Delphi , Файловая система , Файлы

Быстрое копирование с диска на дискету и обратно

Фармацевтика - наука о форматировании диска C.

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

Программа на языке Delphi, демонстрирующая быстрый способ копирования файлов из одной папки в другую. Функция CopyFile принимает два параметра типа string, FromPath и ToPath, которые представляют собой пути к исходному и целевому файлам соответственно.

Функция использует функции AssignFile и Reset для открытия файла-источника для чтения и файла-назначения для записи. Затем она рассчитывает общую размерность файла-источника с помощью функции FileSize.

Массив буфера объявлен размером 16384 байт (16 КБ), который являетсяcommon block size for disk I/O operations. Функция GetMem используется для выделения памяти под этот буфер.

Затем функция входит в цикл, который читает блоки данных из файла-источника с помощью функции BlockRead и записывает их в файл-назначение с помощью функции BlockWrite. Цикл продолжается до тех пор, пока не будет прочитано все содержимое или не произойдет ошибка.

Если количество байт, написанных, не равно количеству байт, прочитанным, функция возвращает значение -1, указывая на то, что произошла ошибка.

Функция UnCompress использует алгоритм сжатия LZ (Lempel-Ziv) для раскрытия сжатого файла и сохранения его в новом месте. Функция принимает три параметра типа string: src, dest и Error. Параметр src - это имя исходного файла, dest - это имя целевого файла, а Error - это параметр вывода, который возвращает код ошибки.

Функция использует функции LZOpenFile и LZCopy для открытия файла-источника для чтения и файла-назначения для записи, а затем вызывает LZCopy, чтобы раскрыть файл. Параметр Error устанавливается в значение возвращаемое LZCopy, которое указывает на то, произошла ли ошибка.

Функция UnCompressError используется для обработки ошибок, возникших при процессе раскрытия. Она отображает сообщение об ошибке в зависимости от типа ошибки.

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

Некоторые предложения для улучшения кода:

  1. Обработка ошибок: Код не обрабатывает ошибки должным образом. Например, если произойдет ошибка при операциях ввода-вывода файлов, программа будет завершаться внезапно без предоставления полезной информации пользователю.
  2. Сжатие: Функция UnCompress использует третьестороннюю библиотеку сжатия (LZ), которая может не быть совместима с некоторыми версиями Delphi или платформами.
  3. Размер буфера: Буфер размером 16 КБ, используемый в функции CopyFile, может не быть подходящим для больших файлов или файлов с разными блок-сizes.
  4. Конвенции именования файлов: Код предполагает, что имена файлов являются валидными и не содержат специальных символов. Лучше будет проверять имена файлов перед использованием их.

Альтернативное решение:

Вместо реализации собственной функции копирования файлов можно использовать компонент TFileStream в Delphi для копирования файлов. Этот компонент обеспечивает более robust и эффективный способ чтения и записи файлов.

Пример кода, демонстрирующий использование TFileStream для копирования файлов:

uses
  Classes, SysUtils;

procedure CopyFile(SrcName, DestName: string);
var
  SrcFile, DestFile: TFileStream;
begin
  // Открываем файл-источник для чтения
  SrcFile := TFileStream.Create(SrcName, fmOpenRead or fmShareDenyWrite);
  try
    // Открываем файл-назначение для записи
    DestFile := TFileStream.Create(DestName, fmCreate or fmShareExclusive);
    try
      // Копируем содержимое файла из источника в назначение
      SrcFile.CopyFrom(DestFile, SrcFile.Size);
    finally
      // Закрываем и освобождаем файл-назначение
      DestFile.Free;
    end;
  finally
    // Закрываем и освобождаем файл-источник
    SrcFile.Free;
  end;
end;

В этом коде используются TFileStream для открытия файла-источника для чтения и файла-назначения для записи. Затем используется метод CopyFrom, чтобы скопировать содержимое файла из источника в назначение. Наконец, файлы закрываются и освобождаются с помощью метода Free.

Быстрое копирование файлов с диска на дискету и обратно: методики и примеры кода для ускорения операции.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Файлы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-15 22:39:35/0.0044050216674805/0