Здравствуйте. Установлена RAD Studio 11.3, у которой отсутствует вкладка BDE и, соответственно, компонент Table, который обеспечивает доступ к таблице средствами механизма BDE.
|
Побайтовое копирование / перенос файлов
Далее мы проверяем – хватает ли нам информации для копирования или переноса, то есть выбрал ли пользователь, что копировать, и куда. Если нет – выводим сообщение и выходим, ничего не делая.
Далее как обычно, мы связываем файлы с файловыми переменными, открываем первый файл для чтения, другой для записи.
Обнуляем переменные, которые будут работать в качестве счетчиков прочитанных и записанных байт. Интересна строка
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;
Вот и вся программа! На первый взгляд она сложна, но если проанализировать код и попробовать указанные приемы в различных примерах, то программа окажется не такой уж и сложной, ведь все используемые функции и процедуры нам уже знакомы. Сохраните проект, скомпилируйте и посмотрите, как работает программа. Файлы небольших размеров будут обрабатываться моментально, чтобы вы успели разглядеть процесс, выбирайте файлы побольше. Размер буфера можно было бы уменьшить, но это приведет к увеличению цикла копирования, что снизит скорость обработки файла, а увеличение буфера ощутимого ускорения не принесет.