□ Построчная буферизация . В этом случае библиотека выполняет фактический ввод/вывод (т.е. производит системные вызовы read(2) или write(2) ) построчно при обнаружении конца строки (символа перевода каретки). Такой тип буферизации обычно используется для ассоциированных с терминальными устройствами потоков, которыми, как правило являются стандартные потоки ввода и вывода.
□ Отсутствие буферизации . В этом случае библиотека не производит никакой буферизации, фактически являясь только программной оболочкой системных вызовов. При этом достигаются минимальные задержки операций чтения и записи, необходимые, например, при выводе сообщений об ошибках. Отсутствие буферизации характерно для стандартного потока вывода сообщений об ошибках.
Характер буферизации может быть изменен с помощью функций:
#include
void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int type, size_t size);
Функция setbuf(3S) позволяет включить или отключить буферизацию для потока stream
. В первом случае buf
должен указывать на буфер размером BUFSIZ
, во втором его значение должно быть равно NULL
.
Функция setvbuf(3S) позволяет производить более тонкое управление буферизацией, явно указывая, какой ее тип мы хотим установить. Для этого используется аргумент type
, который может принимать следующие значения:
_IOFBF |
Полная буферизация |
_IOLBF |
Построчная буферизация |
_IONBF |
Отсутствие буферизации |
В случае полной или построчной буферизации аргумент size
определяет размер буфера, адресованного указателем buf
.
Каждый поток стандартной библиотеки представлен указателем на структуру FILE
, показанную на рис. 2.9, в которой хранится указатель на буфер _base
, указатель на следующий символ, подлежащий чтению или записи _ptr
, число байт в буфере _cnt
, указатель на файловый дескриптор _file
, с которым ассоциирован данный поток, а также флаги состояния потока _flag
. При создании буфера библиотека выбирает оптимальный размер для данного потока. Обычно этот размер равен значению поля st_blksize
структуры stat
, возвращаемой системным вызовом stat(2) , рассмотренный в разделе "Метаданные файла" этой главы. Если определить оптимальный размер невозможно, например для каналов или специальных файлов устройств, выбирается стандартное значение BUFSIZ
, определенное в файле .
Рис. 2.9. Структуры данных потока
В метаданных каждого файла файловой системы UNIX хранится число связей, определяющее количество имен, которое имеет данный файл. Например, файлы /etc/init.d/lp(или /etc/lp), /etc/rc0.d/K201p, /etc/rc2.d/K201pи /etc/rc2.d/S801pимеют различные имена, но ссылаются на один и тот же физический файл (точнее, метаданные файла) и тем самым обеспечивают доступ к одним и тем же данным. В данном случае число связей файла равно 4. Каждый раз, когда одно из имен файла удаляется, число связей соответственно уменьшается. Когда оно достигнет нуля — данные файла будут удалены. Такой тип связи называется жесткой .
Жесткая связь создается с помощью системного вызова link(2) :
#include
int link(const char *existing, const char *new);
При этом будет образована новая запись каталога с именем new
и номером inode указывающим на метаданные файла existing
. Также будет увеличено число связей. Этим системным вызовом, в частности, пользуется команда ln(1) , рассмотренная в главе 1.
Для удаления жесткой связи используется системный вызов unlink(2) :
#include
int unlink(const char *path);
Эту функцию вызывает команда rm(1) при удалении файла. При этом не обязательно будут удалены данные файла. Заметим, что системный вызов, явно удаляющий данные файла, отсутствует, поскольку у файла может существовать несколько жестких связей, часть из которых может быть недоступна процессу, вызывающему такую функцию (например, одно из имен файла может быть расположено в недоступном каталоге).
В противоположность жестким связям, которые, как отмечалось в главе являются естественным способом адресации данных файла, в UNIX применяются символические связи, адресующие не данные файла, а его имя. Например, если файл является символической связью, то в его данных хранится имя файла, данные которого косвенно адресуются.
Читать дальше