Ios app c что это
Перейти к содержимому

Ios app c что это

  • автор:

Обработка файлов C ++: разница между ios :: app и ios :: ate?

В чем разница между ios::ate и ios:app при записи в файл.
На мой взгляд, ios::app дает вам возможность перемещаться по файлу, тогда как с ios::ate он может только читать / писать в конце файла. Это правильно?

6 ответов

Все наоборот. Когда установлено ios::ate , исходной позицией будет конец файла, но вы можете свободно искать после этого. Когда установлено ios::app , все операции вывода выполняются в конце файла. Поскольку всем операциям записи неявно предшествует поиск, нет возможности писать в другом месте.

ios::app -> «Мы не можем переместить указатель. Это будет только в конце».

ios::ate -> «Мы можем переместить указатель записи в любое другое место».

Параметр ios::ate предназначен для операций ввода и вывода и ios::app позволяет нам добавлять данные в конец файла.

Они указаны следующим образом (в 27.5.3.1.4 C ++ 11):

app стремятся к концу перед каждой записью

ate открываются и стремятся завершить сразу после открытия

С ios::app позиция записи в файле «липкая» — все записи в конце, независимо от того, где вы ищите.

Это довольно хорошо задокументировано здесь.

ios::ate «устанавливает индикатор положения потока в конец потока при открытии».

ios::app «установить индикатор положения потока в конец потока перед каждой операцией вывода».

Это означает, что разница в том, что ios::ate помещает вашу позицию в конец файла, когда вы его открываете. ios::app вместо этого помещает его в конец файла каждый раз, когда вы сбрасываете поток. Если, например, у вас есть две программы, которые записывают в один и тот же файл журнала, ios::ate переопределит все, что было добавлено в файл другой программой с момента его открытия вашей программой. ios:app вместо этого будет переходить в конец файла каждый раз, когда ваша программа добавляет запись в журнал.

Я добавляю здесь ответ, потому что недавно я столкнулся с ситуацией, когда ios :: ate должен был работать, но большая часть онлайн-документации по этой теме, например эта страница на cplusplus.com, и аналогичные ответы на этот пост оказались лишь частично правильными или, по крайней мере, вводящими в заблуждение.

В чем все правы, так это в том, что ios :: app откроет файл, не удаляя его содержимое, и переместит курсор в конец файла перед КАЖДОЙ записью в файл. Таким образом, использование такой функции, как seekp, более или менее бесполезно, когда файл был открыт с помощью ios :: app, потому что курсор автоматически перемещается в конец файла при каждой записи, прежде чем запись произойдет.

В чем еще все правы, так это в том, что ios :: ate не будет перемещать курсор в конец файла перед каждой записью. Таким образом, такие функции, как seekp, будут работать с ios :: ate. Также технически правильно то, что ios :: ate будет перемещать курсор в конец файла, когда вы его открываете, но это техническая сторона вопроса — см. Следующий абзац.

Что НЕ согласуется с большей частью документации и ответов на форуме, так это то, что на самом деле (пожалуйста, прокомментируйте, если у них есть разумное объяснение моего опыта здесь), открытие файла с помощью ios :: ate приведет к удалению его содержимого, так же, как ios :: trunc. Это оставляет вам не так много отличных вариантов, если вы хотите открыть непустой файл для записи, не удалять его содержимое и сохранить возможность эффективно перемещать позицию в потоке, как в seekp.

Разница между ios :: app и ios :: ate [duplicate]

В чем разница между этими двумя режимами открытия файлов?

ios: ate устанавливает позицию указателя get/put в конец файла = > чтение/запись начинаем с конца, но как он отличается от ios:: app, который снова открывает файл в режиме добавления. но когда я создал поток и открыл его в режиме ios: app, указатель put put по-прежнему указывает на начало, как работает добавление?

Также я понимаю, что ifstream, ofstream и fstream являются классами высокого уровня для управления базовым буфером потока. Значит ли это, что даже в режиме ios: app я могу читать данные из файла?

3 ответа

app поступает из ‘append’ — весь вывод будет добавлен (добавлен) в конец файла. Другими словами, вы не можете писать где-нибудь еще в файле, но в конце

ate come form ‘at end’ — он устанавливает позицию потока в конце файла при его открытии, но вы можете перемещать его (искать) и писать везде, где вам угодно.

ate просто позиционирует вас в конце файла после открытия, и ничего больше. Это не очень полезно для ofstream , по крайней мере, без других флагов, так как файл все равно будет усечен, поэтому начало — это конец. (Чтобы избежать усечения и все еще иметь возможность писать в любом месте файла, вам нужно или в ios::in , даже если вы не собираетесь читать.)

app предотвращает усечение существующего файла и заставляет каждую запись идти в конец файла. Атомно, если это возможно; если другие процессы записывают в один и тот же файл, ваша запись все равно должна заканчиваться. Обратите внимание, однако, что это относится к фактической записи уровня системы. Если, однако, вы пишете строки, размер которых меньше размера буфера, и вы заканчиваете каждую строку с помощью std::endl , вы можете рассчитывать, что каждая строка будет добавляться атомарно, независимо от того, какие другие процессы могут выполняться с файлом. Чтобы быть эффективными, вы, вероятно, захотите использовать pubsetbuf в filebuf , чтобы обеспечить минимальный размер буфера.

На практике я не думаю, что когда-либо использовал их, или нашел их для использования. Проблемы с буферизацией с app , в частности, в целом привели меня к написанию моего собственного streambuf с концептуально неограниченной буферизацией ( std::vector<char> как буфер), который открывает базовый системный файл с эквивалентом app , но гарантирует только запись в него при явной очистке (как в случае с `std:: endl).

Ios app c что это

Для работы с файлами в стандартной библиотеке определен заголовочный файл fstream , который определяет базовые типы для чтения и записи файлов. В частности, это:

ifstream : для чтения с файла

ofstream : для записи в файл

fstream : совмещает запись и чтение

Для работы с данными типа wchar_t для этих потоков определены двойники:

Открытие файла

При операциях с файлом вначале необходимо открыть файл с помощью функции open() . Данная функция имеет две версии:

Для открытия файла в функцию необходимо передать путь к файлу в виде строки. И также можно указать режим открытия. Список доступных режимов открытия файла:

ios::in : файл открывается для ввода (чтения). Может быть установлен только для объекта ifstream или fstream

ios::out : файл открывается для вывода (записи). При этом старые данные удаляются. Может быть установлен только для объекта ofstream или fstream

ios::app : файл открывается для дозаписи. Старые данные не удаляются.

ios::ate : после открытия файла перемещает указатель в конец файла

ios::trunc : файл усекается при открытии. Может быть установлен, если также установлен режим out

ios::binary : файл открывается в бинарном режиме

Если при открытии режим не указан, то по умолчанию для объектов ofstream применяется режим ios::out , а для объектов ifstream — режим ios::in . Для объектов fstream совмещаются режимы ios::out и ios::in .

Однако в принципе необязательно использовать функцию open для открытия файла. В качестве альтернативы можно также использовать конструктор объектов-потоков и передавать в них путь к файлу и режим открытия:

При вызове конструктора, в который передан путь к файлу, данный файл будет автоматически открываться:

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

В процессе работы мы можем проверить, окрыт ли файл с помощью функции is_open() . Если файл открыт, то она возвращает true:

Закрытие файла

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

Стоит отметить, что при компиляции через g++ следует использовать флаг -static , если программа работает со файлами и использует типы из заголовочного файла fstream:

Работа с файлами в С++

Большинство компьютерных программ работают с файлами, и поэтому возникает необходимость создавать, удалять, записывать читать, открывать файлы. Что же такое файл? Файл – именованный набор байтов, который может быть сохранен на некотором накопителе. Ну, теперь ясно, что под файлом понимается некоторая последовательность байтов, которая имеет своё, уникальное имя, например файл.txt . В одной директории не могут находиться файлы с одинаковыми именами. Под именем файла понимается не только его название, но и расширение, например: file.txt и file.dat разные файлы, хоть и имеют одинаковые названия. Существует такое понятие, как полное имя файлов – это полный адрес к директории файла с указанием имени файла, например: D:\docs\file.txt . Важно понимать эти базовые понятия, иначе сложно будет работать с файлами.

Для работы с файлами необходимо подключить заголовочный файл <fstream> . В <fstream> определены несколько классов и подключены заголовочные файлы <ifstream> файловый ввод и <ofstream> файловый вывод.

Файловый ввод/вывод аналогичен стандартному вводу/выводу, единственное отличие – это то, что ввод/вывод выполнятся не на экран, а в файл. Если ввод/вывод на стандартные устройства выполняется с помощью объектов cin и cout , то для организации файлового ввода/вывода достаточно создать собственные объекты, которые можно использовать аналогично операторам cin и cout .

Например, необходимо создать текстовый файл и записать в него строку Работа с файлами в С++ . Для этого необходимо проделать следующие шаги:

  1. создать объект класса ofstream ;
  2. связать объект класса с файлом, в который будет производиться запись;
  3. записать строку в файл;
  4. закрыть файл.

Почему необходимо создавать объект класса ofstream , а не класса ifstream ? Потому, что нужно сделать запись в файл, а если бы нужно было считать данные из файла, то создавался бы объект класса ifstream .

Назовём объект – fout , Вот что получится:

Для чего нам объект? Объект необходим, чтобы можно было выполнять запись в файл. Уже объект создан, но не связан с файлом, в который нужно записать строку.

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

Используя операцию передачи в поток совместно с объектом fout строка Работа с файлами в С++ записывается в файл. Так как больше нет необходимости изменять содержимое файла, его нужно закрыть, то есть отделить объект от файла.

Итог – создан файл со строкой Работа с файлами в С++ .

Шаги 1 и 2 можно объединить, то есть в одной строке создать объект и связать его с файлом. Делается это так:

Объединим весь код и получим следующую программу.

Осталось проверить правильность работы программы, а для этого открываем файл cppstudio.txt и смотрим его содержимое, должно быть — Работа с файлами в С++ .

Для того чтобы прочитать файл понадобится выполнить те же шаги, что и при записи в файл с небольшими изменениями:

  1. создать объект класса ifstream и связать его с файлом, из которого будет производиться считывание;
  2. прочитать файл;
  3. закрыть файл.

В программе показаны два способа чтения из файла, первый – используя операцию передачи в поток, второй – используя функцию getline() . В первом случае считывается только первое слово, а во втором случае считывается строка, длинной 50 символов. Но так как в файле осталось меньше 50 символов, то считываются символы включительно до последнего. Обратите внимание на то, что считывание во второй раз ( строка 17 ) продолжилось, после первого слова, а не с начала, так как первое слово было прочитано в строке 14 . Результат работы программы показан на рисунке 1.

Рисунок 1 — Работа с файлами в С++

Программа сработала правильно, но не всегда так бывает, даже в том случае, если с кодом всё впорядке. Например, в программу передано имя несуществующего файла или в имени допущена ошибка. Что тогда? В этом случае ничего не произойдёт вообще. Файл не будет найден, а значит и прочитать его не возможно. Поэтому компилятор проигнорирует строки, где выполняется работа с файлом. В результате корректно завершится работа программы, но ничего, на экране показано не будет. Казалось бы это вполне нормальная реакции на такую ситуацию. Но простому пользователю не будет понятно, в чём дело и почему на экране не появилась строка из файла. Так вот, чтобы всё было предельно понятно в С++ предусмотрена такая функция — is_open() , которая возвращает целые значения: 1 — если файл был успешно открыт, 0 — если файл открыт не был. Доработаем программу с открытием файла, таким образом, что если файл не открыт выводилось соответствующее сообщение.

Результат работы программы показан на рисунке 2.

Рисунок 2 — Работа с файлами в С++

Как видно из рисунка 2 программа сообщила о невозможности открыть файл. Поэтому, если программа работает с файлами, рекомендуется использовать эту функцию, is_open() , даже, если уверены, что файл существует.

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

Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios_base предусмотрены константы, которые определяют режим открытия файлов (см. Таблица 1).

Таблица 1 — режимы открытия файлов

Константа Описание
ios_base::in открыть файл для чтения
ios_base::out открыть файл для записи
ios_base::ate при открытии переместить указатель в конец файла
ios_base::app открыть файл для записи в конец файла
ios_base::trunc удалить содержимое файла, если он существует
ios_base::binary открытие файла в двоичном режиме

Режимы открытия файлов можно устанавливать непосредственно при создании объекта или при вызове функции open() .

Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции или | , например: ios_base::out | ios_base::trunc — открытие файла для записи, предварительно очистив его.

Объекты класса ofstream , при связке с файлами по умолчанию содержат режимы открытия файлов ios_base::out | ios_base::trunc . То есть файл будет создан, если не существует. Если же файл существует, то его содержимое будет удалено, а сам файл будет готов к записи. Объекты класса ifstream связываясь с файлом, имеют по умолчанию режим открытия файла ios_base::in — файл открыт только для чтения. Режим открытия файла ещё называют — флаг, для удобочитаемости в дальнейшем будем использовать именно этот термин. В таблице 1 перечислены далеко не все флаги, но для начала этих должно хватить.

Обратите внимание на то, что флаги ate и app по описанию очень похожи, они оба перемещают указатель в конец файла, но флаг app позволяет производить запись, только в конец файла, а флаг ate просто переставляет флаг в конец файла и не ограничивает места записи.

Разработаем программу, которая, используя операцию sizeof() , будет вычислять характеристики основных типов данных в С++ и записывать их в файл. Характеристики:

  1. число байт, отводимое под тип данных
  2. максимальное значение, которое может хранить определённый тип данных.

Запись в файл должна выполняться в таком формате:

Такая программа уже разрабатывалась ранее в разделе Типы данных С++ , но там вся информация о типах данных выводилась на стандартное устройство вывода, а нам необходимо программу переделать так, чтобы информация записывалась в файл. Для этого необходимо открыть файл в режиме записи, с предварительным усечением текущей информации файла (строка 14). Как только файл создан и успешно открыт (строки 16 — 20), вместо оператора cout , в строке 22 используем объект fout . таким образом, вместо экрана информация о типах данных запишется в файл.

Нельзя не заметить, что изменения в программе минимальны, а всё благодаря тому, что стандартный ввод/вывод и файловый ввод/вывод используются абсолютно аналогично. В конце программы, в строке 45 мы явно закрыли файл, хотя это и не обязательно, но считается хорошим тоном программирования. Стоит отметить, что все функции и манипуляторы используемые для форматирования стандартного ввода/вывода актуальны и для файлового ввода/вывода. Поэтому не возникло никаких ошибок, когда оператор cout был заменён объектом fout .

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

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