Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное пособие ОАиП.doc
Скачиваний:
11
Добавлен:
25.04.2019
Размер:
2.63 Mб
Скачать

Потоки и файлы

Перед тем как начать изучение файловой системы языка С, необходимо уяснить, в чем разница между потоками и файлами. В системе ввода/вывода С для программ поддерживается единый интерфейс, не зависящий от того, к какому конкретному устройству осуществляется доступ. То есть в этой системе между программой и устройством находится нечто более общее, чем само устройство. Такое обобщенное устройство ввода или вывода (устройство более высокого уровня абстракции) называется потоком, в то время как конкретное устройство называется файлом. Очень важно понимать, каким образом происходит взаимодействие потоков и файлов.

Файлы Основные сведения о файловой системе

Файловая система ввода/вывода в языке С реализуется с помощью взаимосвязанных библиотечных функций, а не ключевых слов. Для их работы требуется заголовок #include <stdio.h>. Это позволяет подключить файл stdio.h, содержащий прототипы функций ввода/вывода и определяет следующие три типа: size_t, fpos_t и FILE. Типы size_t и fpos_t представляют собой определенные разновидности цело беззнакового типа. А о третьем типе, FILE, рассказывается в следующем разделе. Кроме этого определяются несколько макросов: NULL, EOF, FOPEN_MAX, SEEK_SET, SEEK_CUR и SEEK_END. Макрос NULL определяет пустой (null) указатель. Макрос EOF, часто определяемый как -1, является значением, возвращаемым тогда, когда функция ввода пытается выполнить чтение после конца файла. FOPEN_MAX определяет целое значение, равное максимальному числу одновременно открытых файлов. Другие макросы используются вместе с функцией fseek(), выполняющей операции прямого доступа к файлу.

Файл – это именованный объект, хранящий данные любого типа на каком-либо носителе. Файлы используются для размещения данных, предназначенных для длительного хранения. Каждому файлу присваивается уникальное имя, используемое далее для обращения к нему. Файл, как и массив, – это совокупность данных в этом их сходство, но также существуют и некоторые различия:

- файлы, в отличие от массивов, располагаются не в оперативной памяти, а на некотором носителе информации, в том числе и на электронном диске (в оперативной памяти);

- файл не имеет фиксированной длины, то есть может увеличиваться и уменьшаться;

- перед работой с файлом его необходимо открыть, а после работы – закрыть.

В языке С имеются два способа работы с файлами: через указатель на тип FILE и используя дескриптор файла. Рассмотрим вначале организацию работы с файлами основанную на использовании указателя. Указатель файла определяет конкретный файл и используется соответствующим потоком при выполнении функций ввода/вывода. Для выполнения в файлах операций чтения и записи, программы должны использовать указатели соответствующих файлов. Указатель на файл – это переменная, идентифицирующая конкретный дисковый файл (его адрес) и используется для организации ввода/вывода. Он указывает на структуру FILE, содержащую различные сведения о файле, такие как, имя файла, статус и указатель текущей позиции в начало файла и другие. Описание указателя на файл имеет вид:

FILE *f;

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

FILE *fopen(const char *физическое_имя_файла, const char *режим);

Режим указывает на строку содержащую режим открытия файла. Возможны следующие режимы (табл. 11):

Таблица 11.

режим

Действие

“r”

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

“w”

Создает файл для записи

“a”

Открывает файл для дозаписи в конец файла

“rb”

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

“wb”

Открывает двоичный файл для записи

“ab”

Открывает двоичный файл для дозаписи в конец файла

“r+”

Открывает текстовый файл для чтения/записи

“w+”

Создает текстовый файл для чтения/записи

“a+”

Открывает или создает текстовый файл для чтения/записи

“r+b”

Открывает двоичный файл для чтения/записи

“w+b”

Открывает двоичный файл для чтения/записи

“a+b”

Открывает или создает двоичный файл для чтения/записи

“rt”

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

“wt”

Открывает текстовый файл для записи

“at”

Открывает текстовый файл для дозаписи в коне файла

“r+t”

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

“w+t”

Открывает текстовый файл для чтения/записи

“a+t”

Открывает или создает текстовый файл для чтения/записи

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

FILE *f;

f = fopen("test", "r+");

Более правильно данный код написать немного иначе:

FILE *f;

if ((f = fopen("test","r+"))==NULL)

{ printf("Ошибка при открытии файла.\n");

exit(1);

}

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

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

int fclose(FILE *f);

где f — указатель файла. Возвращение нуля означает успешную операцию закрытия. В случае же ошибки возвращается EOF. Чтобы точно узнать, причину ошибки, можно использовать функцию ferror().

Далее кратко остановимся на некоторых, наиболее важных функциях языка С, обеспечивающих работу с файлами по организации ввода и вывода информации. В таблице приведен список наиболее часто используемых из них.

Таблица . Функции файловой системы С

Наименование

Назначение функции

fopen()

Открывает файл

fclose()

Закрывает файл

putc(), fputc()

Записывает символ в файл

getc(), fgetc()

Читает символ из файла

fgets()

Читает строку из файла

fputs()

Записывает строку в файл

fseek()

Устанавливает указатель текущей позиции на определенный байт файла

ftell()

Возвращает текущее значение указателя текущей позиции в файле

fprintf()

Для файла то же, что printf() для консоли

fscanf()

Для файла то же, что scanf() для консоли

feof()

Возвращает значение true если достигнут конец файла

ferror()

Возвращает значение true, если произошла ошибка

rewind()

Устанавливает указатель текущей позиции в начало файла

remove()

Стирает файл

fflush()

Дозапись потока в файл