Binary vs ASCII Files

I'm not here to start a debate between which is better, but I am unsure of the exact differences and why those differences exist.

From, what I understand if you write an ASCII file it will be formatted differently per OS (Windows/Max/Linux/etc.)
std::ofstream * file = new std::ofstream("file");

However, if you write to binary it will not format to any specific OS. Is this all that there is?
std::ofstream * file = new std::ofstream("file", std::ios_base::binary);

I see answers from around the web saying that each has their own advantages, but I can't think of any for ASCII.
Semantically, the main differences between them is how they are passed. In general, ASCII (or text) files can be simpler to parse, and are also endian independent and will work on any machine - you'll get the same results if you parse it the same way. Its also human-readable, which is a good thing - if you need to modify it you don't need any programs to do it for you.

A binary file is generally used because it is more space efficient, i.e. rather than storing the number 101 (3 bytes) you'd store it as the character 'e' (1 byte). However, you need to be able to know that 'e' is referring to the number 101, rather than the letter 'e' or as part of the data for some other data type. Also, on different machines the byte order for a number is different, so it could end up with something completely different on some machines.

On an unrelated note, why are you defining your file streams on the heap? Just define them with automatic duration like normal people. This isn't Java :)
std::ofstream file("file");
Last edited on
(std::ofstream("file.txt", ios::binary)<< "testing").close();

In java, that operation is overcomplicated... but I digress...

Unless you really want to output somthing other than text, I suggest you use strings. Evidently, there is no difference on linux. I have tested, and passing integers to the stream operators doesn't make a difference: it still outputs their characters.
Thanks for the replies.

@NT3

That's pretty interesting. I've been casting my numbers into characters. I believe I'm using reinterpret_cast<const char*> or something similar to that. I wonder if I can just output the numbers to binary files without converting them. That would be pretty interesting. Working with files has really been interesting especially as it relates to binary.

@IWishIKnew

I've been working on something that packs files into one archive and organizes them. Creating the headers for each file needs to be within a certain size limit. Truthfully that size limit is arbitrary, but I like to keep it below 512 or 256 bytes. It's amazing how 64-bit only needs 8 bytes in binary but like 20 in decimal.
Last edited on
You can. Really, with binary files and ascii files, there is no difference. What the std::ios::binary flag does is to disable processing on what you print, i.e. stop changing \n to \r\n on Windows, or other things like that.

Really, the main difference is how you intend to read and write to them. For an ASCII, you would just use the stream operators or similar, while with binary you would be using reinterpret_casts to print the data in raw, 'binary' form.

On a side note, if you intend to do a lot with binary files, I would suggest you take a look at Boost.Serialize - it fixes a few of the downsides listed above with binary files, but keeping most of the advantages. Get it at http://www.boost.org
Hmm, I suspected that there wasn't a huge difference. It's amazing how operating systems are so different. Ah, I'm glad that the binary tag is available. It makes portability much easier.

I spent a few hours looking at boost. It looks interesting. 10 "modules" of boost made it into C++11. I wonder if any more will make it into C++14. I think I will definitely spend some time to look at it.
Topic archived. No new replies allowed.