fopen(3) Library Functions Manual fopen(3)

fopen, fdopen, freopen - funkcje otwarcia strumienia

Standardowa biblioteka C (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);
Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

fdopen():

    _POSIX_C_SOURCE

Funkcja fopen() otwiera plik, którego nazwę wskazuje pathname i wiąże z nim strumień.

Argument mode wskazuje na łańcuch rozpoczynający się jednym z poniższych ciągów (mogą po nich występować dodatkowe znaki, zgodnie z opisem poniżej):

Otwarcie pliku tekstowego do odczytu. Strumień wskazuje początek pliku.
Otwarcie pliku do odczytu i zapisu. Strumień wskazuje początek pliku.
Usunięcie zawartości pliku lub utworzenie nowego pliku tekstowego do zapisu. Strumień wskazuje początek pliku.
Otwarcie do odczytu i zapisu. Jeśli plik nie istnieje, zostaje utworzony, w przeciwnym wypadku jego zawartość zostaje usunięta. Strumień wskazuje początek pliku.
Otwarcie do dopisywania (zapisu na końcu pliku). Jeśli plik nie istnieje, zostaje utworzony. Strumień wskazuje na koniec pliku.
Otwarcie do dopisywania (zapisu na końcu pliku). Jeśli plik nie istnieje, zostaje utworzony. Wyjście jest zawsze dopisywane na końcu pliku. POSIX milczy na temat początkowej pozycji odczytu, przy korzystaniu z tego trybu. W przypadku glibc, początkową pozycją pliku do odczytywania jest początek pliku, lecz Android/BSD/MacOS ustawiają początkową pozycję pliku do odczytywania na końcu pliku.

Łańcuch mode może także zawierać literę „b” zarówno jak ostatni znak jak też jako znak umieszczony pomiędzy znakami dowolnego dwuznakowego łańcucha opisanego powyżej. Służy to wyłącznie zgodności z ISO C i nie powoduje żadnego efektu, „b” jest ignorowane we wszystkich systemach zgodnych z POSIX, włączając Linuksa (inne systemy mogą różnie traktować pliki tekstowe i pliki binarne; dodanie „b” może być dobrym pomysłem, jeśli wykonywane są operacje wejścia/wyjścia dla pliku binarnego a przewidywane jest przeniesienie programu do środowisk nieuniksowych).

Więcej informacji o rozszerzeniach glibc dla mode zawarto w UWAGACH.

Wszystkie pliki będą tworzone z uprawnieniami S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666), zmodyfikowanymi przez wartość umask procesu (patrz umask(2)).

Odczyt i zapis może występować w strumieniu do zapisu/odczytu w dowolnej kolejności. Należy zauważyć, że ANSI C wymaga interwencji funkcji ustalającej pozycję pliku pomiędzy zapisem i odczytem, chyba że operacja odczytu napotka koniec pliku. (Jeśli ten warunek nie jest spełniony, operacja odczytu może zwrócić wynik innego zapisu niż ostatni.) Tak więc dobrą zasadą (i czasami konieczną pod Linuksem) jest wstawianie funkcji fseek(3) lub fsetpos(3) pomiędzy operacjami zapisu i odczytu na takim strumieniu. Ta operacja może być pozornym rozkazem pustym, no-op, (tak jak w fseek(..., 0L, SEEK_CUR) wywoływanym w celu wykorzystania ubocznych skutków synchronizujących.

Otwarcie pliku w trybie dopisywania (a jako pierwszy znak mode) powoduje, że wszystkie późniejsze operacje zapisu do tego strumienia wystąpią na końcu pliku, tak jakby były poprzedzone wywołaniem


fseek(stream, 0, SEEK_END);

Deskryptor pliku związany ze strumieniem jest otwierany w taki sposób, jak przy wywołaniu open(2) z następującymi znacznikami:

tryb fopen() znaczniki 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

Funkcja fdopen() wiąże strumień z istniejącym deskryptorem pliku, fd. Łańcuch mode strumienia (jeden z „r”, „r+”, „w”, „w+”, „a”, „a+”) musi być zgodny z trybem otwarcia deskryptora pliku. Pozycja nowego strumienia jest taka sama, jak pozycja deskryptora fd, a znaczniki błędu i końca pliku są wyłączane. Tryby „w” oraz „w+” nie powodują usunięcia zawartości pliku. Deskryptor pliku nie jest powielany i zostanie zamknięty w chwili zamknięcia strumienia utworzonego za pomocą fdopen(). Rezultat wywołania funkcji fdopen() dla obiektu pamięci dzielonej jest niezdefiniowany.

Funkcja freopen() otwiera plik, którego nazwa jest zawarta w łańcuchu wskazywanym przez pathname i wiąże z nim strumień wskazywany przez stream. Pierwotny strumień jest zamykany (jeśli istnieje). Argument mode ma takie samo znaczenie jak w przypadku funkcji fopen().

Jeśli argument pathname jest wskaźnikiem pustym, freopen() zmienia tryb strumienia na tryb określony w mode; to jest freopen() otwiera ponownie ścieżkę, która jest związana ze strumieniem. Określenie tego zachowania zostało dodane w standardzie C99, które opisuje go następująco:

W takim przypadku, deskryptor pliku związany ze strumieniem nie musi być zamknięty, jeśli wywołanie do freopen() powiedzie się. Od implementacji zależy, które zmiany trybów są dozwolone (o ile w ogóle) i w jakich okolicznościach.

Podstawowym zastosowaniem funkcji freopen() jest zmiana pliku związanym ze standardowym strumieniem tekstowym (stderr, stdin lub stdout).

Jeśli funkcja fopen(), fdopen() czy freopen() zakończy się pomyślnie, zwraca wskaźnik do struktury FILE. W przeciwnym wypadku zwraca NULL a zmiennej globalnej errno nadawana jest wartość określającą rodzaj błędu.

Argument mode podany dla fopen(), fdopen() lub freopen() jest nieprawidłowy.

Funkcje fopen(), fdopen() i freopen() mogą także zakończyć się niepowodzeniem i ustawić wartość errno na dowolny błąd wymieniony w opisie funkcji malloc(3).

Funkcja fopen() może także zakończyć się niepowodzeniem i ustawić wartość errno na dowolny błąd wymieniony w opisie funkcji open(2).

Funkcja fdopen() może także zakończyć się niepowodzeniem i ustawić wartość errno na dowolny błąd wymieniony w opisie funkcji fcntl(2).

Funkcja freopen() może także zakończyć się niepowodzeniem i ustawić wartość errno na dowolny błąd wymieniony w opisie funkcji open(2), fclose(3) i fflush(3).

Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).

Interfejs Atrybut Wartość
fopen(), fdopen(), freopen() Bezpieczeństwo wątkowe MT-bezpieczne

C11, POSIX.1-2008.
POSIX.1-2008.

POSIX.1-2001, C89.
POSIX.1-2001.

Biblioteka GNU C umożliwia stosowanie następujących rozszerzeń dla łańcucha podanego w mode:

W przypadku operacji otwarcia lub kolejnych operacji odczytu i zapisu, nie robi punktów anulowania (cancellation point) wątku. Znacznik ten jest ignorowany w przypadku fdopen().
Otwiera plik ze znacznikiem O_CLOEXEC. Więcej informacji w podręczniku open(2). Znacznik ten jest ignorowany w przypadku fdopen().
Próbuje uzyskać dostęp do pliku za pomocą mmap(2), zamiast wywołań systemowych wejścia/wyjścia (read(2), write(2)). Obecnie, próba korzystania z mmap(2) nastąpi tylko, gdy plik jest otwierany do odczytu.
Otwiera plik na wyłączność (jak przy znaczniku O_EXCL open(2)). Jeśli plik już istnieje, fopen() zawodzi i ustawia errno na EEXIST. Znacznik ten jest ignorowany w przypadku fdopen().

Oprócz powyższych znaków, fopen() i freopen() obsługują ponadto następującą składnię w mode:

,ccs=łańcuch

Podany string jest przyjmowany jako nazwa zakodowanego zestawu znaków, a strumień jest oznaczany jako zorientowany szeroko. Od tego momentu, wewnętrzna funkcje konwertujące przekształcają wejście/wyjście na i z zestawu znaków string. Jeśli nie użyje się składni ,ccs=string, to szerokie zorientowanie strumienia jest ustalane po pierwszej operacji na pliku. Jeśli operacja ta działa na szerokich znakach, to strumień jest oznaczany jako zorientowany szeroko i ładowane są funkcje służące do konwersji na zakodowany zestaw znaków.

Przy przetwarzaniu mode pod kątem wyodrębnienia poszczególnych znaków znaczników (tj. znaków poprzedzających określenie „ccs”), implementacja glibc fopen() i freopen() ogranicza liczbę znaków sprawdzanych w mode do 7 (lub, przed glibc 2.14, do 6, co nie było wystarczające do uwzględnienia możliwych określeń takich jak „rb+cmxe”). Bieżąca implementacja fdopen() sprawdza co najwyżej 5 znaków w mode.

open(2), fclose(3), fileno(3), fmemopen(3), fopencookie(3), open_memstream(3)

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Adam Byrtek <alpha@irc.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.

2 maja 2024 r. Linux man-pages 6.9.1