Random File Access

  1. So far we have read files sequentially, one character after the other. This is called sequential access.

  2. In random file access, any character can be read directly without first having to read all the characters ahead of it.

  3. To provide random access, each file stream object establishes a file position marker. This marker is a long integer represents an offset from the beginning of the file and keeps track of where the next character is to be read from or written to.

  4. The member functions that can be used to access and change the position marker are listed as follow:

    seekg(offset, mode) - For input files, move to the offset position as indicated by the mode.

    seekp(offset, mode) - For output files, move to the offset position as indicated by the mode.

    tellg(void) - For input files, return the current value of the file position marker.

    tellp(void) - For output files, return the current value of the file position marker.

    The 3 possible modes are: ios::beg, ios::cur, and ios::end, which denote the beginning, current position, and the end of the file, respectively.

  5. The first character in a file has 0 offset, the second character has an offset of 1, and so on for each character in the file.

  6. For example if ins has been opened as an input file and outs as an output file:

    ins.seekg(4L,ios::beg); // go to the 5th character in the input file

    outs.seekp(4L,ios::beg); // go to the 5th character in the output file

    ins.seekg(4L,ios::cur); // move ahead 5 characters in the input file

    outs.seekp(4L,ios::cur); // move ahead 5 characters in the output file

    ins.seekg(-4L,ios::cur); // move back 5 characters in the input file

    outs.seekp(-4L,ios::cur); // move back 5 characters in the output file

    ins.seekg(-4L,ios::cur); // go to 10 characters before the end of the input file

    outs.seekp(-4L,ios::cur); // go to 10 characters before the end of the output file


  7. Here is an example of using some of these features:

    /*
    Reading a file backwards.
    */

    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <string>

    using namespace std;

    int main( )
    {
        const string fileName("test.txt");
        char ch;
        long offset, last;

        ifstream ins(fileName.c_str());
        if (!ins)
        {
           cout << "\nInput file \"test.txt\" cannot be opened\n";
           exit(1);
        }

        ins.seekg(0L,ios::end);
        last = ins.tellg();

        cout << last << endl;

        for (offset = 1L; offset <= last; offset++)
        {
           // the first offset is -1L, representing the first char preceding the EOF marker
           ins.seekg(-offset,ios::end);
           ins.get(ch);
           cout << ch;
        }
        cout << endl;
        ins.close();

        return 0;
    }