Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lektsii_po_si.doc
Скачиваний:
13
Добавлен:
12.11.2018
Размер:
11.78 Mб
Скачать

7.2.1. Открытие / закрытие файла

До выполнения операций ввода-вывода в файл (из файла) на низком уровне необходимо открыть или создать файл одной из следующих функций: open( ), sopen( ) или creat( ).

Функция sopen( ) используется в том случае, когда необходимо дать возможность одновременного доступа к файлу для нескольких выполняющихся программ. Разумеется, речь идет о доступе к файлу в режиме чтения. Обычно файл блокируется для доступа со стороны других выполняющихся программ, и именно функция sopen( ) необходима для разрешения одновременного доступа.

При открытии файла в программу возвращается дескриптор файла, значение которого является целочисленным. В отличие от дескриптора указатель на поток есть указатель на структуру типа FILE, определенного в заголовочном файле stdio.h.

Формат вызова функции open( ), в результате выполнения которой приобретает значение дескриптор файла:

fd = open ( имя_файла, флаги, права_доступа);

В программе дескриптор файла fd должен быть определен как int fd. Параметр имя_файла является указателем на массив символов, содержащий имя файла.

Второй параметр флаги определяет режим открытия файла, который является выражением, сформированным (с помощью '|' - побитовой операции ИЛИ) из одной или более предопределенных констант, размещенных в заголовочном файле fcntl.h. В некоторых реализациях UNIX эти константы находятся в файле sys/file.h.

Примечание. Обратите внимание на то, что в UNIX при образовании полного имени файла применяется символ '/' (прямой слэш), а не обратный слэш ('\'), как в MS-DOS.

Приведем в алфавитном порядке список констант, задающих режим открытия файла, с кратким описанием их назначения:

O_APPEND

O_BINARY

O_CREAT

O_EXCL

O_RDONLY

O_RDWR

О_ТЕХТ

О_ТЕХТ

- открыть файл для добавления (для записи в конец файла);

- открыть файл в бинарном режиме (см §7.1.1);

- создать и открыть новый файл;

- если он указан вместе с флагом O_CREAT и файл уже существует, то функция открытия файла завершается с ошибкой. Этот флаг позволяет избежать непреднамеренного уничтожения уже существующего файла;

- открыть файл только для чтения;

- открыть файл и для чтения, и для записи;

- открыть файл в текстовом режиме (см.§7.1.1);

- открыть существующий файл и стереть его содержимое (подготовить для записи новой информации).

Обратите внимание на то, что режим открытия файла должен быть задан обязательно, так как его значение по умолчанию не устанавливается.

Третий параметр - права_доступа должен применяться только в режиме открытия файла O_CREAT, т.е. только при создании нового файла.

В операционных системах MS-DOS и Windows для задания параметра права_доступа используются следующие предопределенные константы:

S_IWRITE - разрешить запись в файл;

S_IREAD - разрешить чтение из файла;

S_IREAD|S_IWRITE - разрешить и чтение, и запись (совпадает с S_IWRITE).

Перечисленные константы размещены в заголовочном файле stat.h, находящемся в каталоге sys системы программирования Си. Обычно его подключение осуществляется директивой #include <sys\stat.h>.

Если параметр права_доступа не указан, то устанавливается разрешение только на чтение из файла. Чаще всего в операционных системах MS-DOS и Windows этот параметр не используется.

В UNIX в силу того, то она является многопользовательской, система защиты файлов более развита. Права доступа к файлам устанавливаются для трех категорий пользователей:

• владелец файла;

• участник группы пользователей;

• прочие пользователи.

Права доступа к конкретному файлу устанавливаются владельцем файла специальными командами. Права доступа отображаются при просмотре оглавления каталога командой Is -I в виде символьной строки, которая формируется по следующему правилу: для каждой группы пользователей в строке прав доступа выделяется 3 символа, каждый из которых может принимать следующие значения:

r- разрешено чтение из файла;

w - разрешена запись в файл;

x - разрешено выполнение файла (для файлов, хранящих исполняемую программу).

Символы r, w, x задаются строго на своих местах в указанном порядке (rwx). Если какой-либо из типов доступа к файлу запрещен, на месте соответствующего символа записывается символ '-' (минус). Таким образом, если для владельца файла разрешены все виды доступа к файлу (rwx), для участника группы пользователей - только чтение и выполнение (r-х), а для прочих пользователей - только выполнение (--х), то строка прав доступа будет выглядеть так:

От этой строки символов легко перейти к собственно параметру права_доступа, являющемуся целым числом. Если на соответствующем месте в строке указан символ, отличный от '-', то записывают '1', иначе - записывают '0'. Получившееся двоичное число (111101001) переводят в восьмеричное, записав в виде восьмеричной цифры каждую группу из трех двоичных цифр, начиная с самой правой группы: 0751. Это число и следует указать в качестве параметра права_доступа в функции ореn( ).

Приведем несколько примеров открытия файла.

1. Открыть файл для чтения:

2. Открыть существующий файл для записи новых данных:

Параметр права_доступа, заданный восьмеричной константой 0600 (для UNIX), в символьном изображении имеет вид rw-------, т.е. для владельца файла разрешены чтение и запись, для двух других категорий пользователей не разрешен ни один из видов доступа к файлу. Если файл с именем new.txt существует, то перед записью новых данных он будет усечен до нулевого размера (очищен). При открытии файла с указанными параметрами в других ОС параметр права_доступа опускается.

3. Открыть файл для добавления:

4. Открыть файл для чтения и записи:

5. Создать новый файл для записи:

В операционной системе UNIX такая последовательность операторов открывает новый файл для записи. Если файл не существует, то он создается. Иначе функция завершается неудачей. Флаг O_EXCL специально задан для предотвращения непреднамеренного уничтожения уже существующего файла. Этот флаг используется совместно с O_CREAT. Права доступа (rw-rw-rw-) разрешают чтение и запись в файл для всех категорий пользователей. В других ОС параметр права_доступа должен быть опущен.

Приведем более полный пример создания файла (MS-DOS, Windows):

Создаваемый файл в соответствии с выбранными флагами открывается для чтения и записи. Права доступа (rw---) позволяют только владельцу работать с файлом (читать и писать).

Для идентификации ошибок, возникающих при открытии файла, используется именующее выражение (переменная) errno, определенное в заголовочном файле errno.h. При выполнении функций стандартной библиотеки в область памяти, именуемой errno, записываются коды ошибок. Предопределенная в errno.h константа EEXIST означает, что файл, указанный в функции ореп(), уже существует. В этом примере для вывода сообщения об ошибке применена функция форматного вывода в файл fprintf( ), в которой использован предопределенный дескриптор файла stderr стандартного потока для вывода сообщений об ошибках.

Кроме функции ореn( ), для открытия файла можно использовать функцию creat( ), упомянутую в начале параграфа. Функция creat( ) полностью эквивалентна такому вызову функции ореn( ):

open (имя_фаила, O_CREAT|O_TRUNC|O_WRONLY);

Функция creat( ) создает новый файл и открывает его для записи. Наличие в библиотеке наряду с функцией ореn( ) функции creat( ) вызвано требованиями совместимости с ранними версиями UNIX, имевшими только три основных режима открытия файла (O_RDONLY, O_WRONLY, O_RD\VR), что вынуждало использовать для создания нового файла специальную функцию creat( ).

Так же как и при использовании потоков, в начале работы каждой программы автоматически открываются файлы стандартного ввода, стандартного вывода и стандартного вывода сообщений об ошибках. Эти файлы имеют значения дескрипторов файлов 0, 1 и 2, которые можно использовать при обменах на нижнем уровне со стандартными файлами.

Необходимо иметь в виду, что в каждой операционной системе имеется ограничение на количество одновременно открытых в программе файлов. Обычно их число устанавливается от 20 до 40. Во время работы программы, в которой обрабатывается большое количество файлов, необходимо своевременно закрывать ненужные файлы. Для закрытия файла на нижнем уровне служит функция close(), прототип которой имеет вид:

int close (дескриптор_файла);

Функция close( ) при успешном завершении возвращает 0. В случае ошибки возвращается -1.

При завершении программы все открытые файлы автоматически закрываются.