Thursday, 8 January 2009

More on Random Access - Data Schemes

You have total freedom to derive your own schemes. If the blocks of data (records) are all the same length and stored one after another (like the chess positions) then you can easily calculate the position of record n (where n is 0..max number of records -1). Record n is at n* sizeof(record). If records vary in length (e.g. say you are storing lines in a text editor to disk) then you need to maintain a table of offsets. If the first record is 20 chars long and the 2nd one 45 then record 0 starts at 0, record 1 at 20 and record 2 at 65.

These days with the prevalence of cheap or free databases such as SQLite, MySql and SQL Server 2005 Express, there is less of a need to use random access on binary files. Databases are for another lesson though. In a sense, random access file records is an old fashioned technique but still useful. Serialization is probably more common.

I've used various data handling schemes based on random access files in the past before databases were commonplace. You might want to hold a game map as a file of class objects and fetch the object at location x,y. If the map is say 64 x 64 then the first 64 file records in row 0 hold locations (0,0) to (63,0), the next 64 hold (0,1) to (63,1) and so on. If the sizeof(map_location) is 20 then the whole file is 64*64*20 = 81,920 bytes long.

The example on the next page implements a simple file holding 1000 strings each 10 characters long. Because a fstream can only move the point where you read or write to a particular byte, you have to know where an individual record starts. If the records are the same length then it's a simple multiplication = record number * sizeof (record). If the records are different length then you have to maintain an index. Example 3 uses an index.

Programming Random Access File I/O in C++

This lesson is about using random access files in C++ and the next lesson will look at working with text files. Apart from the simplest of applications, most programs have to read or write files. Maybe it's just for reading a config file, a text parser or something more sophisticated. As with many C++ programs, some people prefer the old C way of doing things and if that is you, see the C Tutorial on Programming Random Access Files. This tutorial will however be more about the C++ way of implementing it though example 1 is just a wrapper class around C functions.

The basic file operations are

  • open - open a file- specify how its opened (read/write) and type (binary/text)
  • close - close an opened file
  • read - read from a file
  • write - write to a file
  • seek - move a file pointer to somewhere in a file.
There are two fundamental types of file: text and binary. Of these two, binary are generally the simpler to deal with. As doing random access on a text file isn't something you need to do too often, we'll stick with binary files for the rest of this lesson.

The first four operations listed above are for both text and random access files. The last one just for random access which means we can move to any part of a file and read or write data from it without having to read through the entire file. Back thirty years or forty years ago, much data was stored on large reels of computer tape. The only way to get to a point on the tape was by reading all the way through the tape. Then disks came along and it became easy and fast to read from or write to any part of a file.

Wednesday, 7 January 2009

Converting Numbers to Strings

Instead of writing your own function to convert an integer or float to a string, just use the C++ class stringstream (in the sstream header).

In C++:


#include
#include
#include
using namespace std;

void itoa(int num, string & result)
{
stringstream converter;
converter << result=" converter.str();">