home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


How It Works

Reading and writing binary data is more straightforward than text in many ways. There is no need to worry about parsing the data at all—it is ready to be used as soon as it has been read from disk. The complexities arise more from the format chosen to write to disk with than from the actual operation. Database files for commercial programs add much more than the raw data into headers, such as lists of free blocks in the files, which blocks are taken, and perhaps even the structure of the data or the data type in the file.

The key points when dealing with reading and writing binary data are

  Remember not to use the built-in stream extraction and insertion operators. They are designed specifically for text. Overload your own if you must.
  A binary stream will never receive invalid data. As long as the bytes are coming, they are valid. If you need some sort of error check for validity, consider adding some set value to the structure and checking it to make sure the read alignment is on.
  Try to keep the reading and writing of binary data confined to a few functions. This will make troubleshooting easier, as well as maintenance.
  Byte alignment settings will affect the size of the structures written to disk. This can be a problem to deal with when making different versions of a program interact, as well as different operating system platforms.
  Byte ordering is also something to consider when moving data between platforms. Because the program is dealing with binary data, it is vulnerable to differences in the in-memory representation of that data. This is not necessarily the same for all processors, or even all operating systems.

Comments

There are fewer rules for working with raw binary data, but also more things to watch for. This puts the responsibility for an effective implementation more on the programmer. One useful strategy is emulating the streaming functionality and error handling because they are easy to understand for C++ programmers.

15.5 Read from or write to different positions in a file?

Problem

Without the ability to move arbitrarily to different locations in a file, data would have to be read in the same order it was written. This is inconvenient, and all streams objects contain the functionality to move to different locations in the stream.

Technique

IOStreams classes implement two functions to facilitate moving around in a stream. An internal representation of a read/write stream (such as an fstream) contains both a read location and a write location (which are not guaranteed to be pointing at the same location in the stream).

Another thing to keep in mind when working with file streams (and streams in general) is that they are essentially like arrays. An array has an index, and the index moves ahead as your code extracts data from the stream. When code inserts items into a stream, it is like appending data to the array. Seeking is just a matter of repositioning the index in the array. Some streams don’t have a meaningful beginning; for instance, seeking to the beginning to the cout stream does nothing useful. File streams, however, do have a distinct beginning and an end, and that is what makes seeking in these streams worthwhile.

The difference between an array and a stream is that a stream is self-managing. The stream knows where the data is supposed to go, and does its best to make sure everything you feed to the stream gets to where you told the stream to put it.

Stream Position Functions

The following function prototypes are available for working with streams:

Table 15.1 Position-Related Stream Member Functions
streampos istream::tellg() Returns the current position of the input stream.
streampos ostream::tellp() Returns the current position of the output stream.
istream& istream::seekg
( streampos position )
Moves to the absolute position given by position in the stream.
istream& istream::seekg
( streamoff offset, seek
_dir direction)
Moves a set number of bytes based on the current position. seek_dir is an enum that’s declared in the ios base class. ios::beg means to seek from the beginning of the file, ios::cur means seek forward from the current position (if offset is negative, it means backward), and ios::end seeks from the end of the file (which means a negative offset should be specified because the stream cannot go further forward).
ostream& ostream::seekp
( streampos position )
Moves to the absolute position in the output stream.
ostream& ostream::seekp Moves to a relative position in the stream.
(streamoff offset, seek
_dir direction )
See istream::seekg earlier in this table.

The preceding positioning member functions are present in any stream, but vary somewhat in implementation. The positional arguments (offset and position for the preceding functions) are usually long values (hence, the common operating system limitation of a 2GB maximum file size), but this is highly compiler dependent. Most compilers use a defined type that the compiler can easily cast to from a long value, but might support larger numbers. Unless your program needs to work with files larger than 2GB, you are safe in believing that these parameters are long values. Beyond that, it is time to delve into your compiler documentation.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.