Решение задач с использованием файлов.
1. Цель работы:
Изучить особенности работы с текстовыми и бинарными файлами.
Подготовка к работе.
Изучить основные методы обработки текстовых файлов. Необходимо знать, как осуществляется последовательный и произвольный (прямой) доступ к элементам двоичных файлов [лекция 14, 16] и последовательный доступ к элементам текстовых файлов, порядок работы с файлами, основные команды и функции, используемые при обработке файлов.
Теоретическая часть.
Файлы. Типы файлов.
Файл– это именованная область внешней памяти, в которой хранится логически завершенный объем данных. Под файлом также понимают поименованную совокупность данных на внешнем носителе (последовательность или множество однотипных записей).
Файл имеет следующие характерные особенности:
· имеет имя на диске, что дает возможность программам идентифицировать и работать с несколькими файлами;
· длина файла ограничивается только емкостью диска.
Часто бывает необходимо ввести некоторые данные из файла или вывести результаты в файл. Например, бывает необходимо обрабатывать массивы, которые слишком велики, чтобы полностью разместиться в памяти.
Файловая система языков С и С++ состоит как бы из двух уровней:
- логических
- физических (с которыми логические всегда связаны) файлов.
Логический файл описывается как указатель на открываемый поток FILE* и служит средством взаимодействия с логическим файлом. Имя физического файла появляется в программе только один раз, в тот момент, когда происходит открытие файла, осуществляемое функцией fopen(), и одновременно его связывание с логическим файлом.
Понятие файла в памяти ЭВМ не определено, и приобретает смысл только после его связи с внешним физическим файлом.
Различают следующие типы файлов:
- текстовые;
- двоичные.
Текстовый файл– это файл, в котором каждый символ из используемого набора символов хранится в виде одного байта (кода, соответствующего символу). Текстовые файлы разбиваются на несколько строк с помощью специального символа "конец строки". Текстовый файл заканчивается специальным символом "конец файла".
Двоичный файл – файл, данные которого представлены в бинарном виде. При записи в двоичный файл символы и числа записываются в виде последовательности байт (в своем внутреннем двоичном представлении в памяти компьютера).
Особенностью языка С++ является отсутствие в нем структурированных файлов. Все файлы рассматриваются как неструктурированная последовательность байтов. При таком подходе понятие файла распространяется и на различные устройства.
Тип задается:
· с помощью системной переменной _fmode (stdlib.h):
_fmode=O_BINARI (для двоичных, задавать
обязательно)
_fmode=O_TEXT (для текстовых, по умолчанию)
· при открытии файла с помощью задания режима доступа (b -для двоичных, t – для текстовых). Если не задан, то считается, что файл текстовый.
В С++ операции с файлами можно осуществлять в двух режимах: форматированном и потоковом.
Исходя из этого библиотечные функции для работы с файлами делятся на потоковые и префиксные. Их существенное отличие состоит в том, что потоковые функции выполняют дополнительную буферизацию (на уровне библиотечной функции и на уровне операционной системы), а префиксные сразу обращаются к функциям операционной системы. Таким образом, префиксные функции являются блоко-ориентированными, а их использование приносит выигрыш при переносе целой группы файлов (кратной размеру сектора диска 512 байт). Потоковые функции приносят выигрыш при работе с символьными и строковыми данными.
Ввод / вывод в С++ также реализуется:
- с помощью функций, унаследованных от библиотеки С (префиксных);
- с помощью потоков С++.
Смешивать эти два способа в одной программе можно только синхронизировав ввод с помощью функции sync_with_stdio().
Преимущества ввода / вывода в стиле С:
· их удобнее использовать при форматированном выводе в программах, не использующих ООП.
Преимущество использования потоков:
· они легче в использовании в простых случаях ввода/вывода, не требующих форматирования,
· потоковые операции можно переопределить для собственных классов.
Поток– это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику.
Функции библиотеки ввода-вывода языка С++, поддерживающие обмен данными с файлами на уровне потока, позволяют обрабатывать данные различных размеров и форматов, обеспечивая при этом буферизованный ввод и вывод. Таким образом, поток представляет собой этот файл вместе с предоставленными средствами буферизации.
Чтение данных из потока называется извлечением, вывод в поток – помещением (включением).
Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым производится обмен (оперативная память, файл на диске, клавиатура или принтер).
При работе с потоком можно:
· открывать и закрывать потоки (связывать указатели на поток с конкретными файлами);
· вводить и выводить строку, символ, форматированные данные, порцию данных произвольной длины;
· анализировать ошибки ввода-вывода и достижения конца файла;
· управлять буферизацией потока и размером буфера;
· получать и устанавливать указатель текущей позиции в файле.
Физически поток представляет собой файл или устройство (например, клавиатуру или дисплей, рассматривающиеся как частный случай файла).
С потоком связано понятие внутреннего указателя, который определяет позицию, с которой начинается следующая операция чтения или записи. При каждой операции чтения или записи происходит автоматическое перемещение указателя.
Обмен с потоком для увеличения скорости передачи данных производится, как правило, через специальную область оперативной памяти – буфер. То есть буфер – это область оперативной памяти, предназначенная для временного хранения данных во время процессов ввода-вывода информации. Буфер накапливает байты, и фактическая передача данных выполняется после заполнения буфера (рис. 2). При вводе это дает возможность исправить ошибки, если данные из буфера еще не отправлены в программу.
Рис. 2. Буферизация данных при работе с потоками
Рассмотрим особенности работы с файлом в каждом из этих режимов.