FOPEN(3) | Руководство программиста Linux | FOPEN(3) |
fopen, fdopen, freopen - функции для открытия потоков
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *pathname, const char *mode, FILE *stream);
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
fdopen(): _POSIX_C_SOURCE
Функция fopen() открывает файл с именем, которое задано в виде строки в pathname, и связывает его с потоком.
Параметр mode указывает на строку, начинающуюся с одной из следующих последовательностей (за ними могут следовать дополнительные символы, описанные далее):
Строка mode может также содержать символ «b» в качестве последнего символа или символа между двумя символами в любых описанных выше двухсимвольных комбинациях. Это требуется только для совместимости с C89 и не оказывает никакого влияния; символ «b» игнорируется во всех POSIX-совместимых системах, включая Linux. Другие системы могут по-разному обращаться с текстовыми и двоичными файлами, и добавление «b» может оказаться полезным, если вы осуществляете ввод-вывод в двоичный файл и ожидаете, что ваша программа может быть перенесена в не UNIX окружение.
О имеющихся расширениях mode в glibc смотрите ЗАМЕЧАНИЯ далее.
Любой созданный файл будет иметь атрибуты S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666), как изменённые в соответствии со значением umask процесса (смотрите umask(2)).
Чтение и запись могут перемешиваться друг с другом в потоке, открытом для чтения/записи, в любом порядке). Заметим, что в ANSI C требуется, чтобы между выводом и вводом использовались функции позиционирования в файле, если операция ввода не встретила конец файла. Если это условие не выполняется, то при чтении разрешается возвращать результат, не совпадающий с данными самой последней записи. Поэтому рекомендуется (а иногда и действительно необходимо в Linux) использовать функции fseek(3) или fgetpos(3) между операциями чтения и записи в одном потоке. Эти операции могут фактически быть пустыми (например, fseek(..., 0L, SEEK_CUR), вызванная для того, чтобы возник её побочный эффект синхронизации).
Открытие файла в режиме дописывания (a в качестве первого символа mode) приводит к тому, что все последующие операции записи в этот поток производятся в конец файла, как если бы перед ними была вызвана:
fseek(stream, 0, SEEK_END);
Файловый дескриптор, связанный с потоком, открывается как при вызове open(2) со следующими флагами:
режим fopen() | флаги open() |
r | O_RDONLY |
w | O_WRONLY | O_CREAT | O_TRUNC |
a | O_WRONLY | O_CREAT | O_APPEND |
r+ | O_RDWR |
w+ | O_RDWR | O_CREAT | O_TRUNC |
a+ | O_RDWR | O_CREAT | O_APPEND |
Функция fdopen() связывает поток с существующим дескриптором файла fd. Режим mode потока (одно из следующих значений: «r», «r+», «w», ,w+», «a», «a+») должен быть совместим с режимом дескриптора файла. Указатель положения в файле в новом потоке принимает значение, равное значению у fd, а указатели ошибок и конца файла очищаются. Режимы «w» или «w+» не обрезают файл. При этом не делается копия дескриптора файла и он будет закрыт одновременно с закрытием потока, созданного fdopen(). Результат применения fdopen() к общему объекту памяти не определён.
Функция freopen() открывает файл с именем pathname и связывает его с потоком, указанным в stream. Исходный поток (если такой существовал) закрывается. Значение параметра mode такое же как для функции fopen().
Если значение pathname равно указателю null, то freopen() изменяет режим потока на указанный в mode; то есть, freopen() переоткрывает pathname, связанный с потоком. Описание этого поведения было добавлено в стандарт C99, где сказано:
Основной задачей функции freopen() является смена файла, связанного со стандартным текстовым потоком (stderr, stdin или stdout).
При успешном выполнении fopen(), fdopen() и freopen() возвращается указатель FILE. В противном случае возвращается NULL и errno присваивается код ошибки.
Функции fopen(), fdopen() и freopen() могут также завершаться с ошибками и устанавливают значение errno равным какому-либо значению из определённых в malloc(3).
Функция fopen() при ошибках устанавливает значение errno равным какому-либо значению из определённых в open(2).
Функция fdopen() при ошибках устанавливает значение errno равным какому-либо значению из определённых в fcntl(2).
Функция freopen() при ошибках устанавливает errno равным какому-либо значению из определённых в open(2), fclose(3) и fflush(3).
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
fopen(), fdopen(), freopen() | Безвредность в нитях | MT-Safe |
fopen(), freopen(): POSIX.1-2001, POSIX.1-2008, C89, C99.
fdopen(): POSIX.1-2001, POSIX.1-2008.
Библиотека GNU C предоставляет следующие расширения строки в mode:
В дополнении к этим символам, для fopen() и freopen() поддерживается следующий синтаксис в mode:
,ccs=строка
Передаваемая строка используется как имя набора символов и поток помечается как широкосимвольный. С того момента внутренние функции преобразования перекодируют данные ввода-вывода в соответствии с набором символов с именем строка. Если синтаксис ,ccs=строка не указан, то широкосимвольность потока определяется по первой файловой операции. Если это операция является широкосимвольной, то поток помечается как широкосимвольный и загружаются функции для перекодировки.
При анализе отдельных флагов в mode (т. е., символов перед «ccs») реализация glibc для fopen() и freopen() ограничивает количество обрабатываемых в mode символов 7-ю (или, в glibc до версии 2.14, 6-ю, что было недостаточно для включения всех возможных флагов, например «rb+cmxe»). Текущая реализация fdopen() анализирует в mode не более 5 символов.
open(2), fclose(3), fileno(3), fmemopen(3), fopencookie(3), open_memstream(3)
2017-09-15 | GNU |