С++ 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 * и делает прямую копию без форматирования и поэтому безопасен.

Это правда и безопасно? Как насчет эффективности? Любые ошибки? Детали будут высоко оценены.

Спасибо!

Ответ 1

Да (см. 27.6.2.5.3/6, где описывается перегрузка < для streambuf).

Ответ 2

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

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

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();

Ответ 3

В § 27.7.3.6.3 стандарта С++ он упомянул, что 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.