Назад |
Функции ввода-вывода используются в системе UNIX для доступа к содержимому файлов. Они делятся на две основные группы. Первая представляют собой группу системных вызовов и реализует минимальный набор действий, необходимых для чтения (записи) информации. Это как бы нижний уровень. Процедуры, входящие во вторую группу, называются функциями буферизованного или форматированного ввода-вывода. Они используют в своей работе обращения к системным вызовам нижнего уровня для выполнения непосредственного ввода-вывода данных. Функции, описываемые в данном разделе, относятся к первой группе. Процедуры буферизованного ввода-вывода можно найти в [6].
Для доступа к содержимому файла его сначала надо открыть, воспользовавшись системным вызовом open( ). Формат вызова выглядит следующим образом:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open (const char *path, int oflag, mode_t mode);
Здесь path - имя файла, oflag - режим открытия файла, задаваемый при помощи констант:
O_RDONLY | - открыть для чтения; |
O_WRONLY | - открыть для записи; |
O_RDWR | - открыть для чтения и записи. |
Следует отметить, что должна быть задана только одна из трех указанных констант. Следующие константы могут быть использованы при необходимости.
O_APPEND | - добавить данные в конец файла; |
O_CREAT | - создать файл; |
O_EXCL | - возвратить код ошибки, если задан флаг O_CREAT, и файл уже существует; |
O_TRUNC | - урезать открываемый файл до нулевой длины. |
Аргумент mode - задает атрибуты создаваемого файла (см. описание системного вызова mkdir( ) в разделе 1.4.2).
При успешном завершении системный вызов open( ) возвращает дескриптор файла. В случае ошибки открытия файла функция возвращает -1.
Дескриптор файла - это целое число, которое является ссылкой на структуру данных, создаваемую в ядре операционной системы. Она содержит информацию, необходимую для последующих операций ввода-вывода. В структуре находятся такие данные, как размер файла, его расположение на диске и указатель на место относительно начала файла для следующей операции ввода или вывода (текущее положение). Текущее положение устанавливается при открытии файла и изменяется при чтении/ записи.
Ядро системы устанавливает ограничение на количество одновременно открытых одним процессом файлов Их максимальное число может 16 до 64, в зависимости от версии UNIX и конфигурации ядра системы, заданной при генерации.
После того как файл открыт, данные вводятся из него посредством функции read( ):
#include <unistd.h> int read (int fd, void *buff, size_t nbytes);
Здесь fd - дескриптор файла, buff - адрес буфера для приема данных, и nbytes - количество байт, подлежащих вводу из файла. Функция возвращает число считанных байт.
Данные выводятся из памяти в файл системным вызовом write( ):
#include <unistd.h> int write (int fd, void *buff, size_t nbytes);
Функция имеет те же аргументы, что и предыдущая, и возвращает в качестве своего значения количество записанных байт.
После выполнения операций чтения и записи, указатель текущего положения перемещается вперед по файлу на количество веденных или выведенных байт. Изменить текущее положение можно также при помощи системного вызова lseek( ). Его формат следующий:
#include <sys/types.h> #include <unistd.h> int lseek (int fd, off_t offset, int whence);
Аргумент fd задает дескриптор открытого файла, offset - величину смещения в байтах, whence указывает, относительно какой позиции файла задано смещение. Последний аргумент может принимать следующие значения:
SEEK_SET | - относительно начала файла; |
SEEK_CUR | - относительно текущей позиции; |
SEEK_END | - относительно конца файла. |
После выполнения последней операции ввода-вывода с файлом, связанную с ним структуру данных ядра можно освободить, выполнив операцию закрытия. Для этого вызывается процедура close( ):
#include <unistd.h> int close (int fd);
Все открытые файлы автоматически закрываются при завершении процесса.
Приведенный ниже пример иллюстрирует применение описанных системных вызовов и содержит программу, дописывающую строку в конец файла.
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <strings.h> char *file_name = "file.txt"; char *string = "This string to add.\n"; int main ( ) { int fd; if ( (fd = open (file_name, O_WRONLY)) < 0) perror ("open file error"); if (lseek (fd, o, SEEK_END) < 0) perror ("lseek error"); if (write (fd, string, strlen (string)) != strlen (string) perror ("write error"); close (fd); }