C++ предоставляет следующие классы для вывода и ввода символов в/из файлов:
ofstream: Класс потока для записи в файлы
ifstream: Класс потока для чтения из файлов
fstream: Класс потока для записи и чтения в/из файлов
Эти классы унаследованы прямо или косвенно от классов istream и ostream. В этом руководстве мы уже использовали объекты этих типов: cin это объект класса istream и cout это объект класса ostream. Фактически мы можем использовать файловые потоки таким же образом, как используются cin и cout, с тем различием, что мы должны ассоциировать эти потоки с физическими файлами. Давайте рассмотрим пример:
// основные файловые операции
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream myfile;
myfile.open ("example.txt");
myfile << "Writing this to a file.\n";
myfile.close();
return 0;
}
[file example.txt]
Writing this to a file.
Этот код создаёт файл с именем example.txt и вставляет в него последовательность символов таким же образом, как это делается для cout, но используя для этого поток myfile.
Но давайте двигаться шаг за шагом:
Открытие файла
Первая операция, обычно производимая с объектами одного из этих классов, это связывание с реальным файлом. Эта процедура известна как открытие файла. Открытый файл представляет собой в программе поток(т.е. объект одного из этих классов; в предыдущем примере это был myfile) и любая операция ввода или вывода, производимая над этим потоковым объектом, будет применена к ассоциированному физическому файлу.
Чтобы открыть файл потоковым объектом мы используем его метод open:
open (имя_файла, режим);
Где имя_файла это строка, представляющая имя открываемого файла, а режим это опциональный параметр, который может быть комбинацией следующих флагов:
| ios::in | Открыть для чтения |
| ios::out | Открыть для записи |
| ios::binary | Открыть в двоичном режиме |
| ios::ate | Установить начальную позицию в конец файла. Если этот флаг не установлен, начальная позиция будет в начале файла |
| ios::app | Все операции записи будут производиться в конец файла, дополняя уже существующее содержимое файла |
| ios::trunc | Если файл открыт для записи и он уже существует, то старое содержимое файла будет удалено и замещено новым |
Все эти флаги могут быть объединены посредством побитового оператора OR(|). Например, если мы хотим открыть файл example.bin в двоичном режиме для добавления данных, мы можем сделать это следующим вызовом open:
ofstream myfile;
myfile.open ("example.bin", ios::out | ios::app | ios::binary);
Каждый из методов open классов ofstream, ifstream и fstream имеет режим по умолчанию, который используется, если файл открыт без второго аргумента:
| Класс | Режим по умолчанию |
| ofstream | ios::out |
| ifstream | ios::in |
| fstream | ios::in | ios::out |
Для классов ifstream и ofstream автоматически предполагаются соответственно ios::in и ios::out, даже если вторым аргументом в метод open передано значение, не включающее их(флаги комбинируются).
Для fstream значение по умолчанию применяется, если метод open вызван без второго параметра. Если метод вызван с любым значением второго параметра, значение по умолчанию перезаписывается, а не комбинируется.
Файловые потоки, открытые в двоичном режиме, производят операции ввода и вывода независимо от какого-либо формата. Недвоичные файлы известны как текстовые файлы, в них может происходить интерпретация данных из-за форматирования некоторых специальных символов(например, символов новой строки и возврата каретки).
Поскольку первая задача, которая выполняется в файловом потоке, заключается в открытии файла, эти три класса включают конструктор, который автоматически вызывает метод open и имеет точно такие же параметры, что и метод open. Следовательно, мы могли бы также объявить предыдущий объект myfile и выполнить ту же операцию открытия из прошлого примера, написав:
ofstream myfile ("example.bin", ios::out | ios::app | ios::binary);
Комбинируя создание объекта и открытие потока в одном выражении. Обе формы открытия файла корректны и эквивалентны.
Чтобы проверить, что файловый поток успешно открыл файл, вы можете вызвать метод is_open. Этот метод возвращает значение типа bool: true в том случае, если объект потока действительно связан с открытым файлом, иначе — false:
if (myfile.is_open())
{
// Файл успешно открыт
}
Закрытие файла
После завершения операций ввода и вывода с файлом мы должны закрыть его, чтобы уведомить операционную систему и осбоводить ресурсы. Для этого мы вызываем метод close. Этот метод выполняет очистку связанных буферов и закрывает файл:
myfile.close();
После вызова этого метода объект потока может быть снова использован для открытия другого файла, а закрытый файл снова доступен для открытия другими процессами.
В случае уничтожения объекта, всё ещё связанного с открытым файлом, деструктор автоматически вызывает метод close.
Текстовые файлы
.
