Пример copyfile
Теперь можем закрепить материал на практике. Задача состоит в написании функции copyfile, которая будет копировать содержимое одного файла в другой. Возвращаемое значение должно быть равно нулю в случае успеха или отрицательному числу – в случае ошибки.
Основная логика действий понятна: открыть первый файл, затем создать второй и выполнять чтение из первого файла и запись во второй до тех пор, пока не будет достигнут конец первого файла. И, наконец, закрыть оба файла.
Окончательное решение может выглядеть таким образом:
(* Программа copyfile: скопировать файл name1 в файл name2 *)
uses linux;
const
BUFSIZE=512; (* Размер считываемого блока *)
PERM=0644; (* Права доступа для нового файла в форме,
похожей на восьмеричную *)
(* Скопировать файл name1 в файл name2 *)
function copyfile(name1, name2: string):integer;
var
infile, outfile: integer; (*дескрипторы файлов*)
nread: longint;
buffer: array [0..BUFSIZE-1] of byte; (*буфер для чтения/записи*)
begin
infile := fdopen (name1, Open_RDONLY);
if infile=-1 then
begin
copyfile:=-1; (*ошибка открытия первого файла*)
exit;
end;
outfile := fdopen (name2, Open_WRONLY or Open_CREAT or Open_TRUNC, octal(PERM));
if outfile=-1 then
begin
fdclose(infile);
copyfile:=-2; (*ошибка открытия второго файла*)
exit;
end;
(* Чтение из файла name1 по BUFSIZE символов *)
nread := fdread (infile, buffer, BUFSIZE);
while nread > 0 do
begin
(* Записать buffer в выходной файл. *)
if fdwrite (outfile, buffer, nread) < nread then
begin
fdclose (infile);
fdclose (outfile);
copyfile:=-3; (* ошибка записи *)
exit;
end;
nread := fdread (infile, buffer, BUFSIZE);
end;
(*закрываем прочитанные файлы*)
fdclose (infile);
fdclose (outfile);
if (nread = -1) then
copyfile := -4 (* ошибка при последнем чтении *)
else
copyfile := 0; (* все порядке *)
end;
(* Программа для тестирования функции copyfile *)
var
retcode:integer;
begin
if paramcount<2 then
begin
writeln('Используйте: ',paramstr(0),' файл-источник файл-приемник');
exit;
end;
retcode := copyfile(paramstr(1), paramstr(2));
case retcode of
0: writeln('Файл ',paramstr(1),' успешно скопирован в файл ',paramstr(2));
-1: writeln('Ошибка открытия файла ',paramstr(1),' для чтения');
-2: writeln('Ошибка открытия файла ',paramstr(2),' для записи');
-3: writeln('Ошибка записи в файл ',paramstr(2));
-4: writeln('Ошибка чтения из файла ',paramstr(1));
end;
end.
Теперь функцию copyfile можно вызывать так:
retcode := copyfile('squarepeg', 'roundhole');
Упражнение 2.6. Измените функцию copyfile так, чтобы в качестве ее параметров могли выступать дескрипторы, а не имена файлов. Проверьте работу новой версии программы.
Упражнение 2.7. Если вы умеете работать с аргументами командной строки, используйте одну из процедур copyfile для создания программы mycp, копирующей первый заданный в командной строке файл во второй.