Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ fstream << and >> operators with binary data

I've always read and been told that when dealing with binary files that one should use read() and write() as opposed to the << and >> operators as they are meant for use with formatted data. I've also read that it is possible to use them, but it is an advanced topic, which I can't find where anyone dives into and discusses.

I recently saw some code which did the following:

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

 file1 << file2.rdbuf();

When I pointed out the use of the << operator with the binary file, I was told that the rdbuf() call returns a streambuf * and that << overloads the streambuf* and does a direct copy with no formatting and is thus safe.

Is this true and also safe? How about efficiency? Any gotchas? Details would be much appreciated.

Thanks!

like image 893
RC. Avatar asked Aug 14 '09 14:08

RC.


People also ask

What is binary mode in C++?

A binary stream is an ordered sequence of characters that can transparently record internal data. Data read in from a binary stream always equals to the data that were earlier written out to that stream. Implementations are only allowed to append a number of null characters to the end of the stream.

How are binary files different text files in C++?

Text files are organized around lines, each of which ends with a newline character ('\n'). The source code files are themselves text files. A binary file is the one in which data is stored in the file in the same way as it is stored in the main memory for processing.

How do I copy a binary file in C++?

You can use the . read() method of std::ifstream, which enables you to read N bytes of data.


3 Answers

Yes (see 27.6.2.5.3/6 where the overload of << for streambuf is described).

like image 75
AProgrammer Avatar answered Sep 25 '22 07:09

AProgrammer


It's entirely safe and a reasonable way to copy streams.

Note that it also allows stuff like:

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();
like image 41
MSalters Avatar answered Sep 24 '22 07:09

MSalters


In § 27.7.3.6.3 of the C++ standard, it's mentioned that
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 describes "unformatted input" which is basically a binary copy. This means that "unformatted" ostream functions are safe for binary data. The other "unformatted" functions mentioned in the standard that I can find are put, write and (officially) flush.

like image 39
Mooing Duck Avatar answered Sep 25 '22 07:09

Mooing Duck