Общие принципы работы с файлами
При вводе-выводе файл рассматривается как последовательность байтов. Для каждого файла существует текущая позиция, начиная с которой будет выполняться следующая операция чтения или записи. Началу файла соответствует текущая позиция 0. После выполнения каждой операции ввода-вывода значение текущей позиции автоматически увеличивается на число введенных или выведенных байтов.
Пусть, например, мы начинаем чтение с начала файла. Предположим, первая операция чтения ввела 4 байта, интерпретированное как целое число. Тогда текущая позиция для данного файла становится равной 4, это значение указывает на пятый по порядку байт в файле.
Текущую позицию в файле можно явно установить с помощью специальных методов, задавая ее смещение от начала файла, конца файла или от текущего значения. Пусть, например, мы “передвинули” текущую позицию во входном файле на 20 байтов вперед. Тогда, следующая операция чтения начнет ввод именно с этой позиции. Если текущая позиция явным образом не изменяется, чтение и запись файла происходят последовательно.
Режимы открытия файлов
Каждый класс файловых потоков содержит конструкторы, с помощью которых можно создавать объекты этих классов (потоки) различными способами.
Стандартные конструкторы (без параметров) создают объект соответствующего класса, не связывая его с файлом:
- ifstream();
- ofstream();
- fstream().
Конструкторы с параметрами создают объект соответствующего класса (поток), открывают файл с указанным именем и связывают этот файл с созданным потоком:
- ifstream ( const char *name, int mode = ios::in);
- ofstream ( const char *name, int mode = ios:out | ios::trunc);
- fstream ( const char *name, int mode = ios::in | ios::out);
Первым параметром этих конструкторов с параметрами является имя файла, это – единственный обязательный параметр. Вторым формальным параметром является режим открытия файла, для которого определено значение по умолчанию. Если принимаемое по умолчанию значение не устраивает программиста, можно указать другое значение, составив его из одного или нескольких, соединенных операцией побитовое ИЛИ, следующих величин, определенных в классе ios (их значениями являются несовпадающие между собой степени числа 2, в двоичном представлении это 1, 10, 100 и т.п.):
ios::app | – при записи данные добавляются в конец файла, даже если текущая позиция была перед этим перемещена; |
ios::ate | – при создании потока текущая позиция помещается в конец файла, однако в отличие от режима арр запись ведется в текущую позицию; |
ios::in | – поток создается для ввода, если файл уже существует, он сохраняется; |
ios::out | – поток создается для вывода (режим по умолчанию); |
ios::trunc | – если файл уже существует, его предыдущее содержимое уничтожается и длина файла становится равной нулю; режим действует по умолчанию, если не заданы ios::ate, ios::app или ios::in; |
ios::binary | – ввод-вывод будет происходить в бинарном виде, по умолчанию используется текстовое представление данных. |
Можно создать файловый поток с помощью стандартного конструктора без параметров, а позднее выполнить его метод open, связав поток с каким-либо файлом. Метод open имеет такие же формальные параметры, как и соответствующий конструктор с параметрами. Такой “двухступенчатый” способ создания потока, является более гибким, поскольку позволяет после закрытия файла связать данный файловый поток с другим файлом.
Только после того, как поток создан и соединен с определенным файлом (либо с помощью конструктора с параметрами, либо с помощью метода open), можно выполнять ввод-вывод.
После завершения ввода-вывода поток следует закрыть с помощью метода close или уничтожить (удалить), если он был создан с помощью операции new. При выводе метод close завершает вывод содержимого внутреннего буфера в файл и отсоединяет поток от файла, при вводе – отсоединяет поток от файла. То же самое происходит и при уничтожении потока как объекта.