Node:File data corrupted, Next:, Previous:Crash traceback, Up:Running

9.4 Reading and writing binary files

Q: I'm reading/writing data files, but the data gets corrupted.

Q: My program crashes when I read data files, but the same program on Unix works OK.

Q: When I read a file I get only a small portion of it.

Q: I'm trying to open an existing binary file for read/write using the fstream class, but no mater what I do, the file is always truncated after I write to it....

Q: I cannot read anything from a binary file using the ifstream class, even though I use ios::binary!!

A: Are your data files binary? The default file type in DOS is "text", even when you use the read and write library functions. Text files get their newlines converted to CR-LF pairs on write and vice versa on read; reading in "text" mode stops at the first ^Z character. Reading binary files as text will therefore corrupt the data and fail to read all the data you need. You must tell the system that a file is binary through the b flag in fopen, or O_BINARY in open, or use the setmode library function to switch the handle to binary mode (the latter method is handy when you didn't open the file in your code, like what happens with standard input and output).

Note that the above distinction between binary and text files is written into the ANSI/ISO C standard, so programs that rely on the Unix behavior whereby there's no such distinction, are strictly speaking not portable.

You can also use the low-level _read and _write library functions which give you the direct interface to the DOS file I/O; they always use binary I/O.

If you have problems with read/write access to binary files via the fstream class in C++ programs, then make sure you call the constructor with an explicit ios::in and/or ios::out parameter, like this:

 ifstream object_name ("file", ios::binary | ios::in);

Likewise, if you want to write binary files, you need to mention the ios::out flag explicitly. (This is actually a bug in all versions of the GNU C++ iostreams library up to and including version 2.95.)

Versions of the GNU C++ library before 2.8.1 had a bug in the GNU iostream classes. This bug caused truncation of files, even if you never write to the file. If you still use such an old version and cannot upgrade, a workaround is to do something like this:

 fstream inFile;
 int fd = open ("foobar", O_RDWR | O_BINARY);
 inFile.fstream (fd);