Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика 1.docx
Скачиваний:
11
Добавлен:
26.09.2019
Размер:
364.88 Кб
Скачать

Работа с потоками

Процесс работы с файлами можно разделить на 3 основные части:

  1. Открытие файла (потока). На этой стадии происходит инициализация всех процессов операционной системы, ответственных за работу с внешними носителями, в том числе, поиск файла.

  2. Считывание данных из файла (потока) или запись данных в файл (поток). Считываемые данные поблочно считываются из файла в буфер в оперативную память, откуда потом побайтно попадают в программу. Записываемые программой в файл данные сначала помещаются в буфер, который по мере заполнения единым блоком записывается в файл.

  3. Закрытие файла (потока). На этой стадии всё содержимое буфера, ещё не записанное в файл, записывается в него. Поэтому отсутствие операции закрытия файла может привести к тому, что часть данных, с точки зрения программы уже записанных в файл, будет потеряна. На этой же стадии освобождается память, выделенная операционной системой под буфер.

Прежде чем начать работать с потоком, его необходимо ини­циализировать - открыть. Для этого в C используется функция fopen.

FILE *fopen( const char *filename, const char *mode ); где

filename – имя файла (с полным путём или относительно текущего каталога).

mode – режим открытия файла.

Основные режимы работы формируется из 2 частей, первая из них отвечает за режим чтения / записи:

"r"

Открытие файла для чтения. Если файл не существует, то функция возвращает ошибку (NULL).

"w"

Открытие файла для записи. Если файл уже существует, то его содержимое будет стёрто.

"a"

Открытие файла для добавления записей в уже существующий файл (без удаления его уже существующего содержимого). Если файл не существует, то его надо создать перед открытием потока с флагом "a".

"r+"

Открытие для чтения и записи (файл должен существовать).

"w+"

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

"a+"

Открытие файла для чтения и добавления записей в уже существующий файл (без удаления его уже существующего содержимого). Если файл не существует, то его надо создать перед открытием потока с флагом "a".

Вторая часть cтроки, на которую указывает переменная mode, отвечвет за режим трансляции символов.

(пусто)

Текстовый режим. Некоторые сочетания байтов (например, символы, отвечающие за перевод строки) транслируется функциями чтения / записи в виде 1 байта вместо нескольких байт, записанных в файле.

T

Модифицированный текстовый режим (только для компиляторов Microsoft). Дополнительная трансляция некоторых сочетаний символов в один символ.

B

Бинарный (двоичный) режим. Не производится никакой трансляции информации – содержимое файла считывается с точностью до байта.

Например, при использовании режима "wb" файл (поток) будет открыт на запись в бинарном режиме.

При использовании режима "r" файл (поток) будет открыт на чтение в текстовом режиме. При этом некоторые символы функциями чтения будут возвращаться не точно в том виде, как они записаны в файле. Например, существуют два различных стандарта на запись символа перевода строки: в стандарте DOS/UNIX он кодируется одним символом с кодом 0x0d, а в стандарте Windows он кодируется двумя символами 0x0d и 0x0a, записанными один за другим. Для того, чтобы программист не беспокоился об этой разнице и программа работала бы для файлов обоих стандартов, в текстовом режиме оба варианта ("\x0D" и "\x0D\x0A") передаются пользователю в виде символа с кодом 0x0d.

При удачном завершении процесса открытии файла, функция fopen возвращает указатель на специальную структуру FILE (что такое структура будет рассказано позже), уникально идентифицирующую открытый с её помощью поток. В противном случае функция fopen возвращает NULL.

После вызова функции fopen всегда обязательно надо проверять возвращаемый результат и делать обработку ошибок. Например, типовая работа с файлами выглядит так:

FILE* stream;

// Открываем файл для чтения

if( (stream = fopen( "data", "r" )) == NULL )

printf( Не могу открыть файл 'data'\n" );

else

{

// Читаем / записываем в файл

// Закрываем файл

if( fclose( stream ) )

printf( "Не могу закрыть файл 'data' \n" );

}

По окончании работы с потоком его необходимо закрыть. Это делается с помощью функции

int fclose( FILE *stream );

которой в качестве аргумента передаётся указатель на идентификатор потока, полученный от функции fopen().

Функция fclose() возвращает 0 в случае успешного завершения (в отличие от fopen(), которая возвращает NULL в случае ошибочного завершения). Поток не может быть закрыт если файл по каким-либо причинам был блокирован операционной системой – в этом случае возвращается ненулевой код (равный константе EOF), индицирующий наличие ошибки. Заметим, что поток надо закрывать только в том случае, если он предварительно был успешно открыт, поэтому в вышеприведённом примере функция fclose() стоит внутри блока оператора if, выполняемого при успешном открытии файла.