Разница между ios:: app и ios:: ate
Возможный дубликат:
С++ Обработка файлов: разница между ios: app и ios: ate?
В чем разница между этими двумя режимами открытия файлов?
ios: ate устанавливает позицию указателя get/put в конец файла = > чтение/запись
начинаем с конца, но как он отличается от ios:: app, который снова открывает файл в режиме добавления... но когда я создал поток и открыл его в режиме ios: app, указатель put put по-прежнему указывает на начало, как работает добавление?
Также я понимаю, что ifstream, ofstream и fstream являются классами высокого уровня для управления базовым буфером потока. Значит ли это, что даже в режиме ios: app я могу читать данные из файла?
Ответы
Ответ 1
app
поступает из 'append' - весь вывод будет добавлен (добавлен) в конец файла. Другими словами, вы не можете писать где-нибудь еще в файле, но в конце
ate
come form 'at end' - он устанавливает позицию потока в конце файла при его открытии, но вы можете перемещать его (искать) и писать везде, где вам угодно.
Ответ 2
ate
просто позиционирует вас в конце файла после открытия, и ничего больше. Это не очень полезно для ofstream
, по крайней мере, без других флагов, так как файл все равно будет усечен, поэтому начало - это конец. (Чтобы избежать усечения и все еще иметь возможность писать в любом месте файла, вам нужно или в ios::in
, даже если вы не собираетесь читать.)
app
предотвращает усечение существующего файла и заставляет каждую запись идти в конец файла. Атомно, если это возможно; если другие процессы записывают в один и тот же файл, ваша запись все равно должна заканчиваться. Обратите внимание, однако, что это относится к фактической записи уровня системы. Если, однако, вы пишете строки, размер которых меньше размера буфера, и вы заканчиваете каждую строку с помощью std::endl
, вы можете рассчитывать, что каждая строка будет добавляться атомарно, независимо от того, какие другие процессы могут выполняться с файлом. Чтобы быть эффективными, вы, вероятно, захотите использовать pubsetbuf
в filebuf
, чтобы обеспечить минимальный размер буфера.
На практике я не думаю, что когда-либо использовал их, или нашел их для использования. Проблемы с буферизацией с app
, в частности, в целом привели меня к написанию моего собственного streambuf
с концептуально неограниченной буферизацией (std::vector<char>
как буфер), который открывает базовый системный файл с эквивалентом app
, но гарантирует только запись в него при явной очистке (как в случае с `std:: endl).
Ответ 3
Если вы посмотрите на, например, эта ссылка, вы увидите:
app seek to the end of stream before each write
и
ate seek to the end of stream immediately after open
Это означает, что ios::app
записывает только в конце, но ios::ate
по умолчанию считывает и записывает в конце. Однако при ios::ate
вы можете свободно искать файл, но с ios::app
вы всегда будете писать в конце, независимо от того, какую позицию вы указали для указателя записи.