Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

1 программа

int open(const char * pathname, int flags); (наш случай)

int open(const char * pathname, int flags, mode_t mode);

Вызов open() создает новый файловый дескриптор типа int для открытого файла и запись в системной таблице открытых файлов, этот дескриптор является ссылкой на запись.
Новый дескриптор открытого файла изначально не разделяется с любым другим процессом, но разделение может возникнуть через fork().

Процесс получает файловый дескриптор типа int @НЮ

FILE * fdopen(int fd, const char * mode);

Передаётся файловый дескриптор, в результате выполнения - указатель на структуру FILE, в ней содержатся флаги, текущий ук-ль для чтения/записи,конец/начало области чтения/записи, поле _ fileno - номер дескриптора открытого файла и т.д.

Файловый дескриптор является объектам процесса, который содержит указатель на объект открытого файла struct file и набора флагов. Каждый дескриптор открытого файла содержит поле f_pos (текущая позиция для чтения/записи), которое начинается с 0.

int setvbuf(FILE *stream, char *buf, int mode , size_t size)

Изменяет буфер, который будет использоваться для операций ввода/вывода. Файл должен быть уже открыт.

Существует три типа буферизации:

  1. нулевая буферизация (ее отсутствие) = информация незамедлительно оказывается на терминале (или в файле назначения)
  2. буферизация блока = полная буферизация = сохраняется большое количество символов (их блок), данные записываются после заполнения буфера. Входной буфер заполняется при открытии файла и, если буфер пуст
  3. буферизация строки = все символы сохраняются в буфере до перевода строки (или когда буфер полон)

Обычно все файлы буферизуются блоком.

Запись из буфера в файл в 3 случаях

  1. буфер заполнен
  2. Функция fflush принуждает закончить буферизацию блока раньше
  3. Функция fclose, но только при закрытии.
Стандартный поток ошибок stderr по умолчанию никогда не буферизуется. 

buf - это буфер, который будет использоваться вместо текущего. Если равен NULL - не определен, система динамически распределяет объем памяти, требуемый функцией setvbuf и использует его в качестве буфера для потока.
mode:

  1. _ IONBF (отключить буферизацию);
  2. _ IOFBF (блочная буферизация);
  3. _ IOLBF (строчная буферизация).

size - размер в байтах

В силу особенностей буферизированного ввода/вывода вызов fscanf считывает в буфер 20 символов,
второй вызов то, что осталось до символа конца файла. 

2 программа

ssize_t read(int fd, void *buf, size_t count)

Пытается записать count байтов файлового дескриптора типа int (fd) в буфер, адрес которого начинается с buf.

ssize_t write(int fd, const void *buf, size_t count)

Записывает до count байтов из буфера buf в файл, на который ссылается файловый описатель fd

Стандартные дескрипторы файлов

0 STDIN стандартный поток ввода
1 STDOUT стандартный поток вывода
2 STDERR стандартный поток ошибок
write(1,&c,1); // пишем 1 байт из с в STDOUT(= 1)

3 программа

struct stat

struct stat {
    dev_t         st_dev;      /* устройство */
    ino_t         st_ino;      /* inode */
    mode_t        st_mode;     /* режим доступа */
    nlink_t       st_nlink;    /* количество жестких ссылок */
    uid_t         st_uid;      /* идентификатор пользователя-владельца */
    gid_t         st_gid;      /* идентификатор группы-владельца */
    dev_t         st_rdev;     /* тип устройства */
                               /* (если это устройство) */
    off_t         st_size;     /* общий размер в байтах */
    blksize_t     st_blksize;  /* размер блока ввода-вывода */
                               /* в файловой системе */
    blkcnt_t      st_blocks;   /* количество выделенных блоков */
    time_t        st_atime;    /* время последнего доступа */
    time_t        st_mtime;    /* время последней модификации */
    time_t        st_ctime;    /* время последнего изменения */
};

Функция stat()

int stat(const char * file_name, struct stat * buf)

Возвращает информацию об указанном файле file_name и заполняет буфер buf. Для этого не требуется иметь права доступа к файлу.

FILE * fopen(const char * path, const char * mode);

Также создает новый файловый дескриптор типа int для открытого файла и запись в общесистемной таблице открытых файлов, но возвращает указатель на FILE.

Указатель на структуру FILE также ссылается на буфер

изображение


Предположения:

  1. 2 программа с read()/write() - пример небуферизированного ввода/вывода
  2. есть такая картинка в л/р
    изображение

ВАЖНО стандартный ввод/вывод (fscanf(), fprintf(), fopen(), fclose()) буферизуется (fs ссылается на буфер)

Файловый дескриптор типа int используется для системных вызовов  
FILE * - для функций стандартной библиотеки ввода/вывода

struct files_struct

Описывает открытые файлы процесса. Каждый процесс имеет собственную таблицу открытых файлов, и она определяется этой структурой.

struct fs_struct

Содержит информацию о ФС, к которой принадлежит процесс.

struct file

Определяет дескриптор открытого файла в системе.

struct inode

Описывает созданный файл.

Связь структур

изображение


Ввод/вывод потоком может быть:

  • буферизованным
  • форматированным
  • неформатированным
  1. Функции fclose(), fopen(), fprintf(), fscanf(), fgetc(), fputc(), fgets(), fputs(), fcloseall(), getc(), gets(), putc(), puts(), getchar() работают с форматированными данными
  2. fread(), fwrite() - неформатированными данными

Кратко об open(), fopen(), fdopen()

  • open() - низкоуровневый вызов
  • fdopen() преобразует дескриптор файла типа int в FILE-абстракцию языка C более высокого уровня
  • fopen() вызывает open() в фоновом режиме и возвращет FILE-указатель напрямую. @https://overcoder.net/q/8873/c-fopen-vs-open