PVOID - Файловый ввод/вывод

Файловый ввод/вывод

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.


Текстовые файлы


.