В C++ файл открывается путем стыковки его с потоком. Имеется три типа потоков: ввода, вывода и ввода/вывода. Для открытия потока ввода необходимо объявить поток как объект класса ifstream. Для открытия потока вывода необходимо объявить его как объект класса ofstream. Потоки, которые выполняют как ввод, так и вывод, должны быть объявлены как объекты класса fstream. Например, следующий фрагмент программы создает один поток ввода, один поток вывода и один поток, способный выполнять как ввод, так и вывод:
ifstream in; // ввод
ofstream out; // вывод
fstream both; // ввод и вывод
После создания потока единственным способом ассоциировать его с файлом является использование функции ореn(). Эта функция является членом каждого из трех классов потока. Она имеет следующий прототип:
void open(const char "filename, int mode, int access=filebuf::openprot);
Здесь filename является именем файла и может включать указание пути. Величина mode определяет, каким способом открывается файл. Mode может принимать одно или более из следующих значений, (определенных в заголовочном файле fstream.h):
ios::app
ios::ate
ios::binary
ios::in
ios::nocreate
ios::noreplace
ios::out
ios::trunc
Можно комбинировать два и более из этих значений, используя побитовое ИЛИ.
ios::app указывает на то, что выводимые данные будут добавляться в конец файла. Это значение может быть использовано только для файлов, для которых возможен вывод. Использование ios::ate вызывает поиск конца файла в момент открытия файла.
ios::in задает возможность ввода из файла. ios::out указывает, что файл предназначен для вывода. Однако создание потока с использованием ifstream задает режим ввода, а создание потока с использованием ofstream задает режим вывода, и в этих случаях нет необходимости задавать указанные выше величины.
ios::nocreate задает такой режим, при котором функция open() может открыть только существующий файл. ios::noreplace не позволяет открыть файл функции ореn(), если файл уже существует, но не указаны атрибуты ios::ate или ios::app.
ios::trunc обусловливает уничтожение содержимого файла с заданным именем и усечение длины файла до нуля.
Режим ios::binary обусловливает открытие файла для двоичных операций. Это означает, что не будет никаких преобразований символов.
Величина access определяет, каким образом осуществляется доступ к файлу. Значения атрибута файлов определяются следующим образом:
Атрибут | Значение |
---|---|
0 | Нормальный файл, отрытый доступ |
1 | Файл только для чтения |
2 | Скрытый файл |
4 | Системный файл |
8 | Архивный файл |
С помощью операций побитового ИЛИ можно задать одновременно несколько атрибутов. Обычно эти атрибуты оставляются по умолчанию, что соответствует filebuf::openprot и соответствует нормальному файлу.
В следующем фрагменте открывается нормальный файл для вывода:
ofstream out;
out.open ( "test", ios::out, 0);
Тем не менее, практически никогда не бывает подобного вызова функции ореn(), поскольку оба параметра имеют значения по умолчанию: для ifstream значением по умолчанию mode служит ios::in; а для ofstream значение по умолчанию равно ios::out. Параметр доступа access по умолчанию соответствует нормальному файлу, как это уже отмечалось выше. Поэтому предыдущая инструкция будет выглядеть следующим образом:
out.open("test"); // значения по умолчанию для вывода и нормального файла
Для того, чтобы открыть поток одновременно для ввода и вывода, необходимо задать обе величины ios::in и ios::out для режима mode, как показано в следующем примере:
fstream mystream;
mystream.open("test", ios::in | ios::out);
Если функции open() не удается открыть поток, то поток остается равным NULL.
Хотя открытие файла с использованием функции ореn() является вполне допустимым, в большинстве случаев так не делается, потому что классы ifstream, ofstream и fstream содержат конструкторы, автоматически открывающие файл. Конструкторы имеют те же параметры и значения по умолчанию, что и функция ореn(). Поэтому наиболее типичный способ открытия файла выглядит следующим образом:
ifstream mystream("myfile"); // открытие файла для чтения
Если по каким-либо причинам файл не может быть открыт, значение ассоциированного потока будет равно NULL. Можно использовать следующий код для того, чтобы убедиться, что файл действительно открыт:
ifstream mystream("myfile"); // открытие файла для чтения
if (!mystream) {
cout << "Cannot open file.\n"; // обработка ошибки
}
Для того, чтобы закрыть файл, следует использовать функцию-член close(). Например, чтобы закрыть файл, пристыкованный к потоку mystream, используется следующая инструкция:
mystream.close ();
Функция close() не имеет ни параметров, ни возвращаемого значения.