Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по основам алгоритмизации и программи....doc
Скачиваний:
41
Добавлен:
02.11.2018
Размер:
2.69 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 *file_name, const char *mode);

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

Таблица 11.

режим

Действие

r

Файл открывается только для чтения. Если нужного файла на диске нет, то возникает ошибка

w

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

a

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

r+

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

w+

То же, что и для r+

a+

То же, что и для a, только запись можно выполнять в любое место файла. Доступно и чтение файла

t

Файл открывается в текстовом режиме. Указывается поле r, w, a, r+, w+, a+

b

Файл открывается в двоичном режиме. Указывается поле r, w, a, r+, w+, a+

Функция 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 *stream);

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

Если требуется изменить режим доступа к файлу, то для этого сначала необходимо закрыть данный файл, а затем вновь его открыть, но с другими правами доступа. Для этого используют стандартную функцию freopen, описанную в stdio.h как

FILE* freopen (const char* file_name, const char* mode, FILE *stream).

Эта функция сначала закрывает файл, связанный с потоком stream (как это делает функция fopen), а затем открывает файл с именем filename и правами доступа mode, записывая информацию об этом файле в переменную stream.

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

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

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

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

fopen()

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

fclose()

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

putc(), fputc()

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

getc(), fgetc()

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

fgets()

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

fputs()

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

fseek()

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

ftell()

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

fprintf()

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

fscanf()

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

feof()

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

ferror()

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

rewind()

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

remove()

Удаляет файл

fflush()

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