Опубликован: 07.04.2008 | Доступ: свободный | Студентов: 11863 / 2857 | Оценка: 4.44 / 4.10 | Длительность: 20:15:00
Специальности: Программист, Преподаватель
Лекция 26:

Побайтовое копирование / перенос файлов

< Лекция 25 || Лекция 26: 12 || Лекция 27 >

Далее мы проверяем – хватает ли нам информации для копирования или переноса, то есть выбрал ли пользователь, что копировать, и куда. Если нет – выводим сообщение и выходим, ничего не делая.

Далее как обычно, мы связываем файлы с файловыми переменными, открываем первый файл для чтения, другой для записи.

Обнуляем переменные, которые будут работать в качестве счетчиков прочитанных и записанных байт. Интересна строка

Screen.Cursor := crHourGlass; //песочные часы

Если вы выделите форму и посмотрите свойство Cursor, то увидите список, в котором присутствует и указанное значение. Эта команда на время копирования файла делает курсор в виде песочных часов, чтобы пользователь видел, что процесс идет. Потом мы возвращаем курсору исходный вид:

Screen.Cursor := crDefault; //обычный вид курсора

Далее, внутри цикла копирования, мы подсчитываем общий размер прочитанных байт, чтобы потом рассчитать процент проделанной работы и передвинуть индикатор Gauge:

sizeread := sizeread + colRead;
Gauge1.Progress := Round(100*sizeread/sizefile);

Поскольку свойство Progress имеет целый тип, нам приходится округлять полученный результат до ближайшего целого функцией Round().

К сожалению, при копировании обычными средствами Delphi файл успешно копируется и переносится, однако при этом дата и время создания копии будут текущими – ведь для операционной системы мы просто создали новый файл! Для исправления даты мы вызвали процедуру PravkaDate, куда в качестве параметров передали адреса и имена исходного файла и копии. Теперь нам нужно описать эту процедуру, причем сделать это выше той процедуры, из которой мы ее вызываем.

{Процедура исправления даты. x - адрес и имя файла-оригинала,
 y - файла-копии}
procedure PravkaDate(var x, y : String);
//исправление даты и времени создания файла
var
  origin, kopiya : integer; //дескрипторы
  DateOrigin : integer; //время создания
begin
  try
    //открываем файлы:
    origin := FileOpen(x, fmOpenRead);
    kopiya := FileOpen(y, fmOpenWrite);
    //получаем дату:
    DateOrigin := FileGetDate(origin);
    //записываем дату в файл-копию:
    FileSetDate(kopiya, DateOrigin);
  finally
    FileClose(origin);
    FileClose(kopiya);
  end; //try
end;

Эта процедура использует функции WinAPI, которые позволяют совершать над файлами более серьезные действия, но зато они сложнее в использовании. Когда мы открываем файлы, то в переменные – дескрипторы заносится идентификатор открытого файла в виде целого числа. По этому идентификатору происходит дальнейшая работа с файлом. Далее мы получаем дату и время создания файла в формате MS-DOS, который представляет собой длинное целое число. За это у нас отвечает функция FileGetDate(), куда в качестве параметра мы передаем дескриптор нужного файла. Точно так же мы прописываем полученные дату – время в файл – копию с помощью функции FileSetDate(). В конце мы закрываем файлы.

Эту процедуру вы можете выписать отдельно, и потом вставлять в любую программу, где приходится исправлять дату и время у копии.

Далее обрабатываем кнопку "Копировать". Там мы вызываем процедуру копирования, а затем устанавливаем индикатор копирования в ноль. Если этого не сделать, то после каждого копирования этот индикатор будет показывать 100%.

myCopy;
  Gauge1.Progress := 0;

С кнопкой "Перенос" немного сложней. Если пользователь не указал все необходимые параметры, то процедура копирования вернет ему сообщение об этом, и выйдет, ничего не делая. А ведь после этой процедуры нам нужно будет удалить оригинал! Поэтому перед вызовом процедуры удаления нам придется еще раз проверить – все ли заполнил пользователь? Если нет, то удалять оригинал мы не будем:

myCopy;
  Gauge1.Progress := 0;
  if (Edit1.Text='') or (Edit2.Text='') then Exit;
  DeleteFile(Edit1.Text);

Ну, а с кнопками возле наших Edit совсем просто – первый обрабатывает OpenDialog:

if OpenDialog1.Execute then
    Edit1.Text := OpenDialog1.FileName;

А второй обрабатывает SaveDialog:

if SaveDialog1.Execute then
    Edit2.Text := SaveDialog1.FileName;

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

< Лекция 25 || Лекция 26: 12 || Лекция 27 >
Виктор Пелих
Виктор Пелих

Здравствуйте.
Прохожу курс "Введение в программирование на Delphi"
Добрался до Лекции 29: Введение в базы данных.

Установлена RAD Studio 11.3, у которой отсутствует вкладка BDE и, соответственно, компонент Table,  который обеспечивает доступ к таблице средствами механизма BDE.
Поиск в интернете подсказал 
BDE Installer for RAD Studio, Delphi, C++Builder 10.3 Rio
Подскажите, имеется ли ещё возможность использовать механизм BDE в Delphi11 и если такая возможность есть, как подключить BDE к Delphi11?
С уважением...

 

Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?