Что такое ofstream c

Урок №212. Базовый файловый ввод и вывод

Обновл. 15 Сен 2021 |

Работа файлового ввода/вывода в языке C++ почти аналогична работе обычных потоков ввода/вывода (но с небольшими нюансами).

Классы файлового ввода/вывода

Есть три основных класса файлового ввода/вывода в языке C++:

ofstream (является дочерним классу ostream);

fstream (является дочерним классу iostream ).

С помощью этих классов можно выполнить однонаправленный файловый ввод, однонаправленный файловый вывод и двунаправленный файловый ввод/вывод. Для их использования нужно всего лишь подключить заголовочный файл fstream.

В отличие от потоков cout, cin, cerr и clog, которые сразу же можно использовать, файловые потоки должны быть явно установлены программистом. То есть, чтобы открыть файл для чтения и/или записи, нужно создать объект соответствующего класса файлового ввода/вывода, указав имя файла в качестве параметра. Затем, с помощью оператора вставки ( ) или оператора извлечения ( >> ), можно записывать данные в файл или считывать содержимое файла. После проделывания данных действий нужно закрыть файл — явно вызвать метод close() или просто позволить файловой переменной ввода/вывода выйти из области видимости (деструктор файлового класса ввода/вывода закроет этот файл автоматически вместо нас).

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

See line #1!
See line #2!

Обратите внимание, мы также можем использовать метод put() для записи одного символа в файл.

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

Результат выполнения программы:

Хм, это не совсем то, что мы хотели. Как мы уже узнали на предыдущих уроках, оператор извлечения работает с «отформатированными данными», т.е. он игнорирует все пробелы, символы табуляции и символ новой строки. Чтобы прочитать всё содержимое как есть, без его разбивки на части (как в примере, приведенном выше), нам нужно использовать метод getline():

Результат выполнения программы:

See line #1!
See line #2!

Буферизованный вывод

Вывод в языке C++ может быть буферизован. Это означает, что всё, что выводится в файловый поток, не может сразу же быть записанным на диск (в конкретный файл). Это сделано, в первую очередь, по соображениям производительности. Когда данные буфера записываются на диск, то это называется очисткой буфера. Одним из способов очистки буфера является закрытие файла. В таком случае всё содержимое буфера будет перемещено на диск, а затем файл будет закрыт.

Буферизация вывода обычно не является проблемой, но при определенных обстоятельствах она может вызвать проблемы у неосторожных новичков. Например, когда в буфере хранятся данные, а программа преждевременно завершает свое выполнение (либо в результате сбоя, либо путем вызова функции exit()). В таких случаях деструкторы классов файлового ввода/вывода не выполняются, файлы никогда не закрываются, буферы не очищаются и наши данные теряются навсегда. Вот почему хорошей идеей является явное закрытие всех открытых файлов перед вызовом функции exit().

Также буфер можно очистить вручную, используя метод ostream::flush() или отправив std::flush в выходной поток. Любой из этих способов может быть полезен для обеспечения немедленной записи содержимого буфера на диск в случае сбоя программы.

Интересный нюанс: Поскольку std::endl; также очищает выходной поток, то его чрезмерное использование (приводящее к ненужным очисткам буфера) может повлиять на производительность программы (так как очистка буфера в некоторых случаях может быть затратной операцией). По этой причине программисты, которые заботятся о производительности своего кода, часто используют \n вместо std::endl для вставки символа новой строки в выходной поток, дабы избежать ненужной очистки буфера.

Режимы открытия файлов

Что произойдет, если мы попытаемся записать данные в уже существующий файл? Повторный запуск вышеприведенной программы (самая первая) показывает, что исходный файл полностью перезаписывается при повторном запуске программы. А что, если нам нужно добавить данные в конец файла? Оказывается, конструкторы файлового потока принимают необязательный второй параметр, который позволяет указать программисту способ открытия файла. В качестве этого параметра можно передавать следующие флаги (которые находятся в классе ios ):

app — открывает файл в режиме добавления;

ate — переходит в конец файла перед чтением/записью;

binary — открывает файл в бинарном режиме (вместо текстового режима);

in — открывает файл в режиме чтения (по умолчанию для ifstream );

out — открывает файл в режиме записи (по умолчанию для ofstream );

trunc — удаляет файл, если он уже существует.

Можно указать сразу несколько флагов путем использования побитового ИЛИ (|).

ifstream по умолчанию работает в режиме ios::in;

ofstream по умолчанию работает в режиме ios::out;

fstream по умолчанию работает в режиме ios::in ИЛИ ios::out, что означает, что вы можете выполнять как чтение содержимого файла, так и запись данных в файл.

Источник

Функции-члены потока выходного файла

Функции-члены потока вывода делятся на три типа: эквивалентные манипуляторам, выполняющие неформатированные операции записи и изменяющие состояние потока другим образом и при этом не имеющие эквивалентных манипуляторов или операторов вставки. Для последовательного форматированного вывода можно использовать только операторы вставки и манипуляторы. Для двоичного дискового вывода с произвольным доступом следует использовать другие функции-члены с операторами вставки или без них.

Функция open для потоков вывода

Чтобы использовать выходной поток файлов ( ofstream ), необходимо связать этот поток с конкретным дисковым файлом в конструкторе или open функции. При использовании open функции можно повторно использовать один и тот же объект потока с серией файлов. В любом случае аргументы, описывающие файл, одни и те же.

При открытии файла, связанного с выходным потоком, обычно указывается open_mode флаг. Эти флаги, которые определены как перечислители в классе, можно объединять ios с помощью оператора побитового или ( | ). ios_base::openmode Список перечислителей см. в разделе.

Три типовые ситуации для потока вывода используют параметры режима:

Создание файла. Если файл уже существует, старая версия удаляется.

Добавление записей к существующему файлу или создание нового, если он не существует.

Открытие двух файлов в одном и том же потоке, по одному за раз.

put Функция записывает один символ в выходной поток. Следующие две конструкции по умолчанию одинаковы, но вторая зависит от аргументов формата потока:

write Функция записывает блок памяти в поток выходных файлов. Аргумент length указывает количество записанных байт. Следующий пример создает файловый поток вывода и записывает в него двоичное значение структуры Date :

write Функция не останавливается при достижении символа null, поэтому записывается полная структура класса. Функция имеет два аргумента: указатель char и количество символов для записи. Обратите внимание на обязательное приведение до char * адреса объекта структуры.

Функции seekp и tellp

Функция close для потоков вывода

close Функция члена закрывает файл диска, связанный с выходным потоком файлов. Для завершения всех операций вывода на диск файл должен быть закрыт. При необходимости ofstream деструктор закрывает файл, но функцию можно использовать, close Если необходимо открыть другой файл для того же объекта потока.

Деструктор потока вывода автоматически закрывает файл потока только в том случае, если этот файл открыт конструктором или open функцией-членом. Если конструктору передается дескриптор файла для уже открытого файла или используется attach функция-член, необходимо закрыть файл явным образом.

Функции обработки ошибок

Используйте эти функции-члены для проверки на ошибки при записи в поток:

Оператор ! перегружен для выполнения той же функции, что и функция. Таким образом выражение:

void*() Оператор перегружается как противоположный ! оператору; таким образом, выражение:

void*() Оператор не эквивалентен, good так как не проверяет конец файла.

Источник

Работа с файлами в C++. Часть 2 – Библиотека fstream.

Класс ofstream

Обратный классу ifstream, который мы рассмотрели ранее, и призван для записи в файл.

Параметр ios_base::app указывается, если нужно дописывать в конец уже имеющегося файла. Например когда программа ведет лог своей работы

За проверку на открытость файла отвечает все та же is_open()

Принцип тот же. Так же можно проверить открыт ли файл, использовав в логическом выражении саму файловую переменную:

Оператор endl

Аналогично оператору из iostream производит запись перевода каретки на новую строку в текстовых файлах.

Метод write

Используется в бинарных файлах для записи блока памяти (массива байт) в файл как они есть. Любая переменная так же является массивом байт, вернее ее так можно рассматривать. Соответственно этот метод запишет в файл ее машинное представление (тот вид как она выглядит в памяти).

Этот метод принимает два параметра: Указатель на блок данных и количество байт, который этот блок занимает. В примере строка занимает strlen() байт, целое sizeof() (которое даст 4 на 32-х битных операционках для целого и 8 для вещественного).

Еще раз стоит акцентировать, что в отличии от форматированного вывода оператором write() не выводит данные в текстовом представлении.

Метод close

Такой “отложенный” слив называется “Коммитом” (от латинского commit). Кстати этим эффектом весьма удачно пользуются системы управления базами данных, где вставляемые записи попадают в хранилище в памяти (называемой транзакцией). И только после специальной команды скопом пишутся в сам файл базы. Метод close() как раз пример такой команды закрывающей транзакцию вместе с файлом.

Стоит на всякий случай упомянуть, что если нужно произвести коммит данных без закрытия самого файла, нужно применить метод flush()

Источник

Работа с файлами в C++. Часть 1 – Библиотека fstream.

Наиболее частые операции следующее:

Это не все возможности, которые предоставляет библиотека fstream. Рассматривать все сейчас мы не будем, поскольку их круг применения достаточно узок. Познакомимся с вышеперечисленными. Начнем с класса чтения.

Класс ifstream

Предоставляет возможности для чтения файлов. Открыть файл можно двумя способами: вызвав метод open() или указав путь к нему в конструкторе. Вам необходимо подготовить текстовый файл, перед тем, как начать набирать код. На диске d создайте папку с именем 1 и в ней создайте файл с расширением txt – “файл.txt”.

Открытие файла в конструкторе выглядит так:

Так мы просим открыть файл txt с именем файл.txt, который лежит в папке с названием 1, а папка находится на диске d.

Использование метода open() удобно, если программист не хочет сразу привязываться к файлу. Вдруг нужно свойство класса или глобальную переменную, ну а открывать файл уже потом. Если же нужно открыть файл внутри некой функции, поработать с ним и закрыть, то можно прописать путь к файлу прямо в конструкторе. В общем зависит от ситуации.

Открыв файл, желательно прописать проверку: открылся ли он? Так как есть ряд причин, по которым файл может не открыться, а мы этого не увидим. Например, файла с указанным именем нет в прописанной папке или путь указан неверно. Можно пойти двумя путями: проверить переменную файла в логическом выражении (применив оператор “!”, к примеру) или использовать метод is_open() :

Так все отработает нормально и файл откроется:

Что такое ofstream c. Смотреть фото Что такое ofstream c. Смотреть картинку Что такое ofstream c. Картинка про Что такое ofstream c. Фото Что такое ofstream cТеперь попробуйте вписать название папки не 1, а 2 ifstream file ( «d:\\ color : #ff0000;»>2 \\файл.txt”); и снова запустите программу. Так как папки с указанным именем мы не создавали, то и файл, естественно, не может быть открыт:

Что такое ofstream c. Смотреть фото Что такое ofstream c. Смотреть картинку Что такое ofstream c. Картинка про Что такое ofstream c. Фото Что такое ofstream c

Второй вариант проверки с использованием метода is_open() :

Если файл не открыт – желательно обработать ошибку. Как правило, если вся работа программы связана с файлом пишут некое сообщение в консоль, и ставят выход из программы. При серьезных ошибках принято возвращать некий код выполнения (число), который будет характеризовать ту или иную ошибку. Коды для каждого вида ошибок автор программы может придумывать свои. Один из способов обработки ошибок в программе мы рассматривали в статье Исключения в С++.

Если файл успешно открыт, из него можно производить чтение.

Оператор считывания >>

Считает вещественное, целое и строку. Считывание строки закончится, если появится пробел или конец строки. Стоит отметить, что оператор >> применяется к текстовым файлам. Считывание из бинарного файла производить лучше всего с помощью метода read().

Кстати этот оператор достаточно удобен, если стоит задача разделить файл на слова:

Методы getline() и get()

Считывание целой строки до перевода каретки производится так же как и в iostream методом getline(). Причем рекомендуется использовать его переопределеную версию в виде функции, если считывается строка типа string:

Если же читать нужно в массив символов char[], то либо get() либо getline() именно как методы:

Метод read()

Похож на предыдущий пример?

Собственно тут тот же результат – считается указанное количество символов. Исключение только в том, что нельзя указать разделитель. read() применяется для неформатированного ввода. Призван в первую очередь читать бинарные файлы. Поскольку текстовый файл – частный случай бинарного, этот метод вполне применим и к текстовому файлу.

Метод close()

Закрывает файл. Даже добавить нечего. Единственная пожалуй ремарка – от того, что файл, открытый для чтения, не будет закрыт этим методом как правило хуже не станет. Очень редки ситуации, когда открытый для чтения файл портится, если завершить программу не закрывая файл. Связана эта порча прежде всего с нестандартными устройствами типа стримеров на магнитной ленте или каких нибудь потоковых хитрых промышленных контроллерах, но по феншую стоит запомнить – открытый файл должен быть закрыт. Это считается хорошим тоном.

Метод eof()

Проверяет не достигнут ли конец файла. Т.е. можно ли из него продолжать чтение. Выше пример с считкой слов оператором >> как раз использует такую проверку.

Метод seekg()

Производит установку текущей позиции в нужную, указываемую числом. В этот метод так же передается способ позиционирования:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *