What's the difference exactly between opening a file stream in the default text mode and opening it in binary mode? The cplusplus.com article on file i/o mentioned a few things, but I really didn't get the gist of it. Could someone explain it?

Thanks.

Dani AI

Generated

Short version: text mode is a runtime-level translation layer; binary mode gives your program the raw bytes. As and pointed out, text mode may translate platform newline sequences (and other implementation-defined behavior) so that your '\n' in the program becomes the system line ending on disk and vice versa. Use std::ios::binary (or "rb"/"wb" in C) when you need exact bytes, predictable offsets, or are working with non-text data (as and correctly noted).

Why that matters in practice: random access and file-position functions are unreliable in text mode because the runtime may insert or remove bytes during translation — seeking to a byte offset in a text stream can be implementation-defined. Also, writing raw structs directly to disk is fragile: binary dumps depend on endianness, alignment and padding, and compiler/ABI differences. For portable binary data, define an explicit on-disk format (fixed-width integer types, a documented byte order) or use a serialization library.

Quick examples and tips:

std::ifstream in("file.bin", std::ios::binary);
in.read(reinterpret_cast<char*>(&buffer), sizeof(buffer));

FILE* f = fopen("file.bin", "rb");
fread(&buffer, sizeof(buffer), 1, f);

When debugging cross-platform corruption: check whether the file was opened in text mode, inspect the file in a hex viewer (CR/LF show as 0x0D0A), or run a dos2unix/unix2dos conversion if needed. For text data intended for humans, keep text mode; for everything else (images, audio, compressed files, precise binary protocols), open in binary and use unformatted I/O (read/write), not formatted extraction (operator>>), which is for whitespace-delimited text.

In short: was right that disks store bytes only — but text vs binary is about how your runtime maps program data to those bytes. Use binary whenever you need those bytes to be exact.

Recommended Answers

All 7 Replies

A text stream will invoke translation of the system defined newline marker to a \n (on reading), and the reverse \n to system defined on writing.

A binary stream doesn't do this.

There is perhaps an implicit assumption that a file opened in text mode might actually consist only of printable characters and cursor control characters.

from my experience you open up files like mp3's in binary, so that you can read any type of info (not just text) at precise position in files. Text mode is for reading/writing text.

The difference also depends on the operating system -- on *nix there is no difference between text and binary written files because *nix compilers make no translation of the '\n' character in either mode. That is, the file itself will contain the same information whether writting with a stream opened in text or binary mode.

That is not true for files writting by MS-DOS, MS-Windows, and MAC. I don't know about other operating systems such as RISC but I suppose it might be true. On MS-DOS/MS-Windows when a file is opened in text mode the '\n' is translated to "\r\n" when written to the file. MAC it is translated to '\r'. So when read back into the program the "\r\n" (or '\r') is transated back to just '\n'.

from my experience you open up files like mp3's in binary, so that you can read any type of info (not just text) at precise position in files. Text mode is for reading/writing text.

That's what I assumed as well, but writing (and I'm assuming reading) from binary file streams uses chars to transmit the data, so you're still using text. Not that you can't type cast the char to become the type of data you want it to be, or type-cast an different data type to a char to be output.

After all, a hard drive doesn't see chars, or ints, or doubles - it just sees bits. So it really doesn't matter what we output the data as in C++. Once it gets to the hard drive, it becomes bits, and then any program can interpret the data in the file any way it wants.

After all, a hard drive doesn't see chars, or ints, or doubles - it just sees bits. So it really doesn't matter what we output the data as in C++. Once it gets to the hard drive, it becomes bits, and then any program can interpret the data in the file any way it wants.

True, but that doesn't mean the program will interpret the data correctly. Example: move a file written in text mode on MS-Windows to *nix, then use a *nix text editor to read it. Or do the opposite -- move a text file writting on *nix to MS-Windows and use Notepad.exe to read it. In both cases the editor will mis-interpret the line feeds. In some cases the text editor may be smart enough to translate the file correctly, but most simple text editors such as Notepad.exe can not do that.

True, but that doesn't mean the program will interpret the data correctly. Example: move a file written in text mode on MS-Windows to *nix, then use a *nix text editor to read it. Or do the opposite -- move a text file writting on *nix to MS-Windows and use Notepad.exe to read it. In both cases the editor will mis-interpret the line feeds. In some cases the text editor may be smart enough to translate the file correctly, but most simple text editors such as Notepad.exe can not do that.

Ya I know. I was just saying that at first I assumed that a binary file stream would output with something other than chars, but then I realized that the fact that you output with chars disappears as soon as the file reaches the hard drive. It's all bytes by then.

And that's why you must use binary mode for FTP when transferring files from *nix to windows/mac/dos, otherwise the binary data will be corrupted by CRLFs. (and I will never understand that. :))

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.