Назад

Содержание

Вперед


1.4.4. Ввод-вывод данных.

    Функции ввода-вывода используются в системе 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);
}