Системное программирование в unix средствами Free Pascal - страница 47

^

11.3. Открытие и закрытие потоков: процедуры fopen и fclose

Описание
uses stdio;
function fopen(filename:pchar; _type:pchar):pfile;
function fclose(_stream:pfile):integer;
Библиотечные процедуры fopen и fclose являются эквивалентами вызовов fdopen и fdclose. Процедура fopen открывает файл, заданный параметром filename, и связывает с ним структуру TFILE. В случае успешного завершения процедура fopen возвращает указатель на структуру TFILE, идентифицирующую открытый файл, объект PFILE также часто называют открытым потоком ввода/вывода (эта структура FILE является элементом внутренней таблицы). Процедура fclose закрывает файл, заданный параметром _stream, и, если этот файл использовался для вывода, также сбрасывает на диск все данные из внутреннего буфера.
В случае неудачи процедура fopen возвращает нулевой указатель nil, определенный в файле system. В этом случае, так же как и для вызова fdopen, переменная linuxerror будет содержать код ошибки, указывающий на ее причину.
Второй параметр процедуры fopen указывает на строку, определяющую режим доступа. Она может принимать следующие основные значения:

r
Открыть файл filename только для чтения. (Если файл не существует, то вызов завершится неудачей и процедура fopen вернет нулевой указатель nil)
w
Создать файл filename и открыть его только для записи. (Если файл уже существует, то он будет усечен до нулевой длины)
а
Открыть файл filename только для записи. Все данные будут добавляться в конец файла. Если файл не существует, он создается
Файл может быть также открыт для обновления, то есть программа может выполнять чтение из файла и запись в него. Другими словами, программа может одновременно выполнять для файла и операции ввода, и операции вывода без необходимости открывать его заново. В то же время из-за механизма буферизации такой ввод/вывод будет более ограниченным, чем режим чтения/записи, поддерживаемый вызовами fdread и fdwrite. В частности, после вывода нельзя осуществить ввод без вызова одной из стандартных процедур ввода/вывода fseek или rewind. Эти процедуры изменяют положение внутреннего указателя чтения/ записи и обсуждаются ниже. Аналогично нельзя выполнить вывод после ввода без вызова процедур fseek или rewind или процедуры ввода, которая перемещает указатель в конец файла. Режим обновления обозначается символом + в конце аргумента, передаваемого процедуре fopen. Вышеприведенные режимы можно дополнить следующим образом:

r+
Открыть файл filename для чтения и записи. Если файл не существует, то вызов снова завершится неудачей
w+
Создать файл filename и открыть его для чтения и записи. (Если файл уже существует, то он будет усечен до нулевой длины)
а+
Открыть файл filename для чтения и записи. При записи данные будут добавляться в конец файла. Если файл не существует, то он создается
В некоторых системах для доступа к двоичным, а не текстовым файлам, к строке также нужно добавлять символ b, например, rb.
Если файл создается при помощи процедуры fopen, для него обычно устанавливается код доступа octal(0666). Это позволяет всем пользователям выполнять чтение из файла и запись в него. Эти права доступа по умолчанию могут быть изменены установкой ненулевого значения атрибута процесса umask. (Системный вызов umask был изучен в главе 3.)
Следующий пример программы показывает использование процедуры fopen и ее связь с процедурой fclose. При этом, если файл indata существует, то он открывается для чтения, а файл outdata создается (или усекается до нулевой длины, если он существует). Процедура fatal предназначена для вывода сообщения об ошибке, ее описание было представлено в предыдущих главах. Она просто передает свой аргумент процедуре perror, а затем вызывает halt для завершения работы программы.
uses stdio;
const
inname:pchar = 'indata';
outname:pchar = 'outdata';
function fatal(s:pchar):integer;
begin
perror (s);
halt (1);
end;
var
inf,outf:pfile;
begin
inf := fopen (inname, 'r');
if inf = nil then
fatal ('Невозможно открыть входной файл');
outf := fopen (outname, 'w');
if outf = nil then
fatal ('Невозможно открыть выходной файл');
(* Выполняются какие-либо действия ... *)
fclose (inf);
fclose (outf);
halt (0);
end.
На самом деле, в данном случае оба вызова fсlose не нужны. Дескрипторы, связанные с файлами inf и outf, будут автоматически закрыты при завершении работы процесса, и вызов halt автоматически сбросит данные из буфера указателя outf на диск, записав их в файл outdata.
С процедурой fclose тесно связана процедура fflush:
Описание
uses stdio;
function fflush(_stream:pfile):integer;
Выполнение этой процедуры приводит к сбросу на диск содержимого буфера вывода, связанного с потоком _stream. Другими словами, данные из буфера записываются в файл немедленно, независимо от того, заполнен буфер или нет. Это гарантирует, что содержимое файла на диске будет соответствовать тому, как он выглядит с точки зрения процесса. (Процесс считает, что данные записаны в файл с того момента, как они оказываются в буфере, поскольку механизм буферизации прозрачен.) Любые данные из буфера ввода этим вызовом предусмотрительно отбрасываются.
Поток _stream остается открытым после завершения процедуры fflush. Как и процедура fclose, процедура fflush возвращает постоянную EOF в случае ошибки и нулевое значение – в случае успеха. (Значение постоянной EOF задано в файле stdio равным –1. Оно обозначает конец файла, но может также использоваться для обозначения ошибок.)
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат
Реферат