Системное программирование в UNIX средствами Free Pascal

       

в цикл для копирования одного


uses stdio;
(* Считать символ из __stream *)
function getc(__stream:pfile):integer;
(* Поместить символ в __stream *)
function putc(__c:integer;__stream:pfile):integer;
Можно поместить обе процедуры в цикл для копирования одного файла в другой:
var
  с:integer;
  istream, ostream:PFILE;
(* Открыть файл istream для чтения и файл ostream для записи *)
.
.
.
с := getc (istream);
while c<>-1 do
begin
  putc (с, ostream);
  с := getc (istream);
end;
Значение -1
возвращается функцией getc при достижении конца файла, поэтому тип возвращаемого функцией getc значения определен как integer.
На первый взгляд, функции getc и putc могут вызывать определенное беспокойство, поскольку они работают с одиночными символами, а это, как уже было продемонстрировано на примере системных вызовов, чрезвычайно неэффективно. Процедуры стандартного ввода/вывода избегают этой неэффективности при помощи изящного механизма буферизации, который работает следующим образом: первый вызов функции getc приводит к чтению из файла BUFSIZ символов при помощи системного вызова fdread. Данные находятся в буфере, созданном библиотекой и находящемся в пользовательском адресном пространстве. Функция getc возвращает только первый символ. Все остальные внутренние действия скрыты от вызывающей программы. Последующие вызовы функции getc поочередно возвращают символы из буфера. После того как при помощи функции getc программе будут переданы BUFSIZ символов и будет выполнен очередной вызов getc, из файла снова будет считан буфер целиком. Аналогичный механизм реализован в функции putc.
Такой подход весьма удобен, так как он освобождает программиста от беспокойства по поводу эффективности работы программы. Это также означает, что данные записываются большими блоками, и запись в файл будет производиться с задержкой (для терминалов сделаны специальные оговорки). Поэтому весьма неблагоразумно использовать для одного и того же файла и стандартные процедуры ввода/вывода, и системные вызовы, такие как fdread, fdwrite или fdseek. Это может привести к хаосу, если не представлять четко, что при этом происходит. С другой стороны, вполне допустимо смешивать системные вызовы и процедуры стандартного ввода/вывода для разных файлов.
Кроме механизма буферизации стандартный ввод/вывод предоставляет утилиты для форматирования и преобразования, например, функция printf обеспечивает форматированный вывод:
printf('Целое число %d'#10, [ival]);
Кстати, функция printf неявно осуществляет запись в стандартный вывод.

Содержание раздела