Здравствуйте, уважаемые подписчики! Главной темой сегодняшнего выпуска будет копирование файлов. В Win32 существует функция CopyFile, которая работает быстро, никаких проблем с ней не возникает, что же еще нужно? Если копируется большой файл, то это занимает много времени. И все то время программа будет стоять на строчке с вызовом CopyFile. Это означает, что не сможет даже перерисоваться окно. Конечно, копирование файла можно вынести в отдельный поток. Но даже в этом случае не удастся определить процент выполненной работы. Так что, иногда полезно написать свое копирование файла.
Копирование файла
Для этой цели удобно использовать процедуры BlockRead и BlockWrite. Для указания пользователем, какой файл копировать и куда, здесь используется OpenDialog и SaveDialog. Здесь было бы удобно использовать Gauge для отображения процента выполненной работы. Но Gauge - плохо сделанный компонент (не оптимально). Так что здесь это же реализовано "вручную".
Самой сложной задачей является определение времени, которое потребуется на завершение копирования файла. Казалось бы: определить затраченное время, разделить на процент сделанной работы - и вот готовое полное время копирования. Но кэширование и многозадачность сильно портят картину. Наилучшее решение, которое мне пришло в голову, это искать скорость копирования не на основе всего затраченного времени, а на основе последних секунд. Если даже какой-то другой процесс "притормозит" копирование, реакция на это быстро пройдет. Если кто-нибудь придумает решение лучше - напишите, пожалуйста, об этом на delphi4all@narod.ru.
Полезные мелочи
Delphi не позволяет сравнивать записи. Поэтому, чтобы сравнить две переменные типа TPoint, нужно отдельно сравнить поля x и y. Чтобы упростить это сравнение, можно написать comp(p1) = comp(p2). В этом случае будут сравниваться два числа типа comp, занимающие как раз по 8 байт. То есть произойдет сравнение двух областей памяти, в которых лежат p1 и p2. Вот пример использования такого сравнения:
procedure TForm1.Button1Click(Sender: TObject);
var
p1, p2: TPoint;
begin
p1 := Point(20, -45);
p2 := p1;
if comp(p1) = comp(p2)
then ShowMessage('p1 = p2')
else ShowMessage('p1 <> p2');
end;
Вместо comp можно написать любой 8-ми байтовый тип, например, int64.