fopen(3)

ИМЯ
fopen, fdopen, freopen - функции для открытия потоков

LIBRARY
Standard C library (libc, -lc)

СИНТАКСИС
#include <stdio.h>

FILE *fopen(const char *restrict pathname, const char *restrict mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *restrict pathname, const char *restrict mode,
              FILE *restrict stream);

    Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

fdopen():
    _POSIX_C_SOURCE

ОПИСАНИЕ
Функция fopen() открывает файл с именем, которое задано в виде строки в pathname, и связывает его с потоком.

Параметр mode указывает на строку, начинающуюся с одной из следующих последовательностей (за ними могут следовать дополнительные символы, описанные далее):

r   Открыть текстовый файл для чтения. Поток совмещается с началом файла.

r+  Открыть для чтения и записи. Поток совмещается с началом файла.

w   Обрезать файл до нулевой длины или создать текстовый файл для записи. Поток совмещается с началом файла.

w+  Открыть для чтения и записи. Файл создаётся, если его не существует, в противном случае он обрезается. Поток совмещается с началом файла.

a   Открыть для добавления (записи в конец файла). Файл создаётся, если его не существует. Поток совмещается с концом файла.

a+  Открыть для чтения и добавления (записи в конец файла). Файл создаётся, если не существует. Вывод всегда добавляется в конец файла. В POSIX ничего не упоминается о начальном положении при чтении, когда используется данный режим. В glibc начальное положение в файле для чтения устанавливается в начало файла, но в Android/BSD/MacOS начальное положение в файле для чтения устанавливается в конец файла.

The mode string can also include the letter 'b' either as a last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with ISO C and has no effect; the 'b' is ignored on all POSIX conforming systems, including Linux. (Other systems may treat text files and binary files differently, and adding the 'b' may be a good idea if you do I/O to a binary file and expect that your program may be ported to non-UNIX environments.)

О имеющихся расширениях mode в glibc смотрите ЗАМЕЧАНИЯ далее.

Любой созданный файл будет иметь атрибуты S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666), как изменённые в соответствии со значением umask процесса (смотрите umask(2)).

Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file positioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes necessary under Linux) to put an fseek(3) or fsetpos(3) operation between write and read operations on such a stream. This operation may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect).

Opening a file in append mode (a as the first character of mode) causes all subsequent write operations to this stream to occur at end-of-file, as if preceded by the call:

    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()
Функция fdopen() связывает поток с существующим дескриптором файла fd. Режим mode потока (одно из следующих значений: «r», «r+», «w», ,w+», «a», «a+») должен быть совместим с режимом дескриптора файла. Указатель положения в файле в новом потоке принимает значение, равное значению у fd, а указатели ошибок и конца файла очищаются. Режимы «w» или «w+» не обрезают файл. При этом не делается копия дескриптора файла и он будет закрыт одновременно с закрытием потока, созданного fdopen(). Результат применения fdopen() к общему объекту памяти не определён.

  freopen()
Функция freopen() открывает файл с именем pathname и связывает его с потоком, указанным в stream. Исходный поток (если такой существовал) закрывается. Значение параметра mode такое же как для функции fopen().

Если значение pathname равно указателю null, то freopen() изменяет режим потока на указанный в mode; то есть, freopen() переоткрывает pathname, связанный с потоком. Описание этого поведения было добавлено в стандарт C99, где сказано:

    В этом случае файловый дескриптор, связанный с потоком, не нужно закрывать, если вызов freopen() завершился без ошибок. Допустимость изменения режима и при каких условиях определяется реализацией.

Основной задачей функции freopen() является смена файла, связанного со стандартным текстовым потоком (stderr, stdin или stdout).

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Upon successful completion fopen(), fdopen(), and freopen() return a FILE pointer. Otherwise, NULL is returned and errno is set to indicate the error.

ОШИБКИ

EINVAL
    Передано неверное значение mode в fopen(), fdopen() или freopen().

The fopen(), fdopen(), and freopen() functions may also fail and set errno for any of the errors specified for the routine 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()
    C11, POSIX.1-2008.

fdopen()
    POSIX.1-2008.

ИСТОРИЯ

fopen()
freopen()
    POSIX.1-2001, C89.

fdopen()
    POSIX.1-2001.

ЗАМЕЧАНИЯ

  Замечания по glibc
Библиотека GNU C предоставляет следующие расширения строки в mode:

c (начиная с glibc 2.3.3)
    Do not make the open operation, or subsequent read and write operations, thread cancelation points. This flag is ignored for fdopen().

e (начиная с glibc 2.7)
    Открыть файл с флагом O_CLOEXEC. Подробности смотрите в open(2). Этот флаг игнорируется для fdopen().

m (начиная с glibc 2.3)
    Пытаться получить доступ к файлу с помощью mmap(2), а не с помощью системных операций ввода-вывода (read(2), write(2)). В настоящее время mmap(2) используется только для файла, открытого на чтение.

x   Открыть файл в монопольном режиме (как с флагом O_EXCL у open(2)). Если файл уже существует, то fopen() завершается с ошибкой и устанавливает значение errno равное EEXIST. Этот флаг игнорируется для fdopen().

В дополнении к этим символам, для fopen() и freopen() поддерживается следующий синтаксис в mode:

,ccs=строка

Передаваемая строка используется как имя набора символов и поток помечается как широкосимвольный. С того момента внутренние функции преобразования перекодируют данные ввода-вывода в соответствии с набором символов с именем строка. Если синтаксис ,ccs=строка не указан, то широкосимвольность потока определяется по первой файловой операции. Если это операция является широкосимвольной, то поток помечается как широкосимвольный и загружаются функции для перекодировки.

ДЕФЕКТЫ
When parsing for individual flag characters in mode (i.e., the characters preceding the "ccs" specification), the glibc implementation of fopen() and freopen() limits the number of characters examined in mode to 7 (or, before glibc 2.14, to 6, which was not enough to include possible specifications such as "rb+cmxe"). The current implementation of fdopen() parses at most 5 characters in mode.

СМ. ТАКЖЕ
open(2), fclose(3), fileno(3), fmemopen(3), fopencookie(3), open_memstream(3)

ПЕРЕВОД
Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 (https://www.gnu.org/licenses/gpl-3.0.html) или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.