C ++ fstream Операторы ‹* и ›› с двоичными данными

Я всегда читал, и мне говорили, что при работе с двоичными файлами следует использовать read () и write (), а не операторы ‹< и ››, поскольку они предназначены для использования с отформатированными данными. Я также читал, что их можно использовать, но это сложная тема, и я не могу найти, чтобы кто-нибудь погрузился в нее и обсудил.

Недавно я увидел код, который делал следующее:

 std::ifstream file1("x", ios_base::in | ios_base::binary);
 std::ofstream file2("y", ios_base::app | ios_base::binary);

 file1 << file2.rdbuf();

Когда я указал на использование оператора ‹< с двоичным файлом, мне сказали, что вызов rdbuf () возвращает streambuf *, а ‹< перегружает streambuf * и выполняет прямое копирование без форматирования и, таким образом, безопасно.

Это правда и безопасно? Как насчет эффективности? Есть ошибки? Подробности были бы очень признательны.

Спасибо!


person RC.    schedule 14.08.2009    source источник


Ответы (3)


Да (см. 27.6.2.5.3 / 6, где описана перегрузка ‹* для streambuf).

person AProgrammer    schedule 14.08.2009
comment
Это страничка в стандарте что ли? :) Ссылка была бы хороша! - person Skurmedel; 14.08.2009
comment
Это ссылка на параграф в стандарте. Сам стандарт не является общедоступным. Некоторые черновики есть, но у меня нет ссылки. - person AProgrammer; 14.08.2009
comment
Хорошо, спасибо за разъяснения. Они должны сделать стандарт общедоступным. - person Skurmedel; 14.08.2009
comment
Продажа - это то, чем они зарабатывают, поэтому маловероятно. Было бы неплохо, хотя я согласен. Последний черновик версии 98 доступен по адресу ftp.research.att .com / pub / c ++ std / WP / CD2. - person KTC; 14.08.2009
comment
Кто они? ISO и национальные органы не являются коммерческими организациями. Деньги, которые они получают от продажи стандартов, оплачивают их эксплуатационные расходы, а популярные стандарты фактически поддерживают менее популярные. Люди в комитете и их работодатели уже поддерживают этот процесс, уделяя свое время, оплачивая проезд и проживание для встреч, спонсируя встречу, чтобы комнаты и т. Д. Были доступны, и часто платя членские взносы. Такая схема на самом деле не предназначена для PL, но PL для этих организаций является довольно своеобразной областью, и делать исключения для них не имеет смысла. - person AProgrammer; 14.08.2009

Это совершенно безопасный и разумный способ копирования потоков.

Обратите внимание, что он также позволяет такие вещи, как:

std::ifstream file_in1("x1", ios_base::in | ios_base::binary);
std::ifstream file_in2("x2", ios_base::in | ios_base::binary);
std::ofstream file_out("y", ios_base::app | ios_base::binary);

file_out << file_in1.rdbuf() << "\nand\n" << file_in2.rdbuf();
person MSalters    schedule 14.08.2009
comment
У вас есть подробности, почему это безопасно? Я знаю, что вы можете это сделать, и, похоже, это сработает, но мое любопытство заключается в том, что часто можно увидеть, где в ссылках говорится, что ‹( и ›› не предназначены для двоичных данных. Например, работает ли это для текстовых файлов, которые открываются как двоичные, а также для изображений одинаково? - person RC.; 14.08.2009
comment
‹< и ›› - перегруженные операторы. То есть существует множество реализаций. Как правило, они предназначены для текста и будут форматировать свой второй операнд. Однако перегрузка streambuf принципиально отличается от всех остальных. - person MSalters; 17.08.2009

В § 27.7.3.6.3 стандарта C ++ упоминается, что
basic_ostream<charT,traits>& operator<< (basic_streambuf<charT,traits>* sb);
Effects: Behaves as an unformatted output function (as described in 27.7.3.7, paragraph 1).

§ 27.7.3.7 описывает «неформатированный ввод», который по сути является двоичной копией. Это означает, что «неформатированные» функции ostream безопасны для двоичных данных. Другие «неформатированные» функции, упомянутые в стандарте, которые я могу найти, это put, write и (официально) flush.

person Mooing Duck    schedule 21.09.2011