ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 28.04.2024
Просмотров: 56
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
1 ... 6 7 8 9 10 11 12 13 14
104
Режимы. Аргумент mode описывает, как открывать конкретный файл. Данный аргумент может быть представлен одной из следующих строк.
r
— файл открывается для чтения. Поток данных устанавливается в начале файла.
r+
— файл открывается как для чтения, так и для записи. Поток данных уста
навливается в начале файла.
w
— файл открывается для записи. Если файл существует, то он усекается до нулевой длины. Если файл не существует, он создается. Поток данных устанав
ливается в начале файла.
w+
— файл открывается для чтения и для записи. Если файл существует, то он усекается до нулевой длины. Если файл не существует, он создается. Поток данных устанавливается в начале файла.
a
— файл открывается для дополнения в режиме дозаписи. Если файл не суще
ствует, то он создается. Поток данных устанавливается в конце файла. Все вводимые данные дозаписываются в файл.
a+
— файл открывается для дополнения и считывания в режиме дозаписи. Если файл не существует, то он создается. Поток данных устанавливается в конце файла. Все вводимые данные дозаписываются в файл.
ПРИМЕЧАНИЕ
В указанном режиме также может содержаться символ b, хотя в Linux это значение всегда игнорирует- ся. Некоторые операционные системы по-разному обрабатывают текст и двоичные файлы. Сим- вол b означает, что файл должен быть открыт именно в двоичном режиме. Linux, как и все операцион- ные системы, соответствующие стандарту POSIX, воспринимает текст и двоичные файлы одинаково.
В случае успеха функция fopen()
возвращает допустимый указатель
FILE
. При ошибке она возвращает
NULL
и устанавливает errno соответствующее значение.
Например, следующий код открывает для чтения файл
/etc/manifest и ассоци
ирует его с потоком данных stream
:
FILE *stream;
stream = fopen ("/etc/manifest", "r");
if (!stream)
/* ошибка */
Открытие потока данных
с помощью файлового дескриптора
Функция fdopen()
преобразует уже открытый файловый дескриптор (
fd
) в поток данных:
#include
FILE * fdopen (int fd, const char *mode);
Глава 3. Буферизованный ввод-вывод
Режимы. Аргумент mode описывает, как открывать конкретный файл. Данный аргумент может быть представлен одной из следующих строк.
r
— файл открывается для чтения. Поток данных устанавливается в начале файла.
r+
— файл открывается как для чтения, так и для записи. Поток данных уста
навливается в начале файла.
w
— файл открывается для записи. Если файл существует, то он усекается до нулевой длины. Если файл не существует, он создается. Поток данных устанав
ливается в начале файла.
w+
— файл открывается для чтения и для записи. Если файл существует, то он усекается до нулевой длины. Если файл не существует, он создается. Поток данных устанавливается в начале файла.
a
— файл открывается для дополнения в режиме дозаписи. Если файл не суще
ствует, то он создается. Поток данных устанавливается в конце файла. Все вводимые данные дозаписываются в файл.
a+
— файл открывается для дополнения и считывания в режиме дозаписи. Если файл не существует, то он создается. Поток данных устанавливается в конце файла. Все вводимые данные дозаписываются в файл.
ПРИМЕЧАНИЕ
В указанном режиме также может содержаться символ b, хотя в Linux это значение всегда игнорирует- ся. Некоторые операционные системы по-разному обрабатывают текст и двоичные файлы. Сим- вол b означает, что файл должен быть открыт именно в двоичном режиме. Linux, как и все операцион- ные системы, соответствующие стандарту POSIX, воспринимает текст и двоичные файлы одинаково.
В случае успеха функция fopen()
возвращает допустимый указатель
FILE
. При ошибке она возвращает
NULL
и устанавливает errno соответствующее значение.
Например, следующий код открывает для чтения файл
/etc/manifest и ассоци
ирует его с потоком данных stream
:
FILE *stream;
stream = fopen ("/etc/manifest", "r");
if (!stream)
/* ошибка */
Открытие потока данных
с помощью файлового дескриптора
Функция fdopen()
преобразует уже открытый файловый дескриптор (
fd
) в поток данных:
#include
FILE * fdopen (int fd, const char *mode);
Глава 3. Буферизованный ввод-вывод
105
Могут использоваться те же режимы, что и с функцией fopen()
, при этом они должны быть совместимы с режимами, которые изначально применялись для от
крытия файлового дескриптора. Режимы w и w+
можно указывать, но они не будут приводить к усечению файла. Поток данных устанавливается в файловую позицию, которая соответствует данному файловому дескриптору.
После преобразования файлового дескриптора в поток данных вводвывод больше не выполняется напрямую с этим файловым дескриптором. Тем не менее это не возбраняется. Обратите внимание: файловый дескриптор не дублируется, а просто ассоциируется с новым потоком данных. При закрытии потока данных закроется и файловый дескриптор.
В случае успеха fdopen()
возвращает допустимый указатель файла, при ошибке она возвращает
NULL
и присваивает errno соответствующее значение.
Например, следующий код открывает файл
/home/kidd/map.txt с помощью сис
темного вызова open()
, а потом создает ассоциированный поток данных, опираясь на базовый файловый дескриптор:
FILE *stream;
int fd;
fd = open ("/home/kidd/map.txt", O_RDONLY);
if (fd == -1)
/* ошибка */
stream = fdopen (fd, "r");
if(!stream)
/* ошибка */
Закрытие потоков данных
Функция fclose()
закрывает конкретный поток данных:
#include
int fclose(FILE*stream);
Сначала сбрасываются на диск все буферизованные, но еще не записанные данные. В случае успеха fclose()
возвращает
0
. При ошибке она возвращает
EOF
(конец файла) и устанавливает errno в соответствующее значение.
Закрытие всех потоков данных. Функция fcloseall()
закрывает все потоки данных, ассоциированные с конкретным процессом, в частности используемые для стандартного ввода, стандартного вывода и стандартных ошибок:
#define _GNU_SOURCE
#include
int fcloseall(void);
Перед закрытием все потоки данных сбрасываются на диск. Функция является специфичной для Linux и всегда возвращает
0
Закрытие потоков данных
106
Считывание из потока данных
Теперь, когда мы умеем открывать и закрывать потоки данных, поговорим о том, как сделать чтото полезное — как считать поток данных, а затем как записать в него информацию.
Стандартная библиотека C реализует множество функций для считывания из открытого потока данных. Среди них есть как общеизвестные, так и мало
распространенные. В этом разделе мы рассмотрим три наиболее популярных варианта считывания: считывание одного символа в момент времени, считыва
ние целой строки в момент времени, считывание двоичных данных. Чтобы из потока данных можно было считать информацию, он должен быть открыт как поток данных ввода в подходящем режиме, то есть в любом допустимом режи
ме, кроме w
и a
Считывание одного символа в момент времени
Зачастую идеальный принцип вводавывода сводится к считыванию одного сим
вола в момент времени. Функция fgetc()
используется для считывания отдельно
го символа из потока данных:
#include
int fgetc(FILE*stream);
Эта функция считывает следующий символ из stream и возвращает его как unsigned char
, приведенный к int
. Такое приведение осуществляется, чтобы получить достаточно широкий диапазон для уведомлений EOF или описания ошибок: в та
ких случаях возвращается
EOF
. Возвращаемое значение fgetc()
должно быть сохра
нено в int
. Сохранение в char
— распространенный и опасный промах, ведь в таком случае вы не можете обнаруживать ошибки.
В следующем коде мы считываем отдельно взятый символ из stream
, проверяем наличие ошибок и выводим результат как char
:
int c;
c = fgetc (stream);
if (c == EOF)
/* ошибка */
else printf ("c=%c\n", (char) c);
Поток данных, указанный в stream
, должен быть открыт для чтения.
Возврат символа в поток данных. В рамках стандартного вводавывода предо
ставляется функция для перемещения символа обратно в поток данных. С ее по
мощью вы можете «заглянуть» в поток данных и возвратить символ обратно, если окажется, что он вам не подходит:
Глава 3. Буферизованный ввод-вывод