Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

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:

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal