Example
The following example shows the use of class RWFileManager to construct a linked-list of int s on disk. The source code is included in the buildspace\examples\tools directory as fmgrsave.cpp and fmgrrtrv.cpp. When using this example, you must type a carriage return after the last item you want to insert in order to guarantee that it will be added to the list. This is because different compilers handle the occurrence of an EOF on the cin stream differently.
 
#include <rw/filemgr.h> // 1
#include <rw/rstream.h>
struct DiskNode { // 2
int data; // 3
Rwoffset nextNode; // 4
};
int main(){
RWFileManager fm("linklist.dat"); // 5
// Allocate space for offset to start of the linked list:
fm.allocate(sizeof(RWoffset)); // 6
// Allocate space for the first link:
RWoffset thisNode = fm.allocate(sizeof(DiskNode)); // 7
fm.SeekTo(fm.start()); // 8
fm.Write(thisNode); // 9
DiskNode n;
int temp;
RWoffset lastNode;
std::cout << "Input a series of integers, ";
std::cout << "then EOF to end:\n";
while (std::cin >> temp) { // 10
n.data = temp;
n.nextNode = fm.allocate(sizeof(DiskNode)); // 11
fm.SeekTo(thisNode); // 12
fm.Write(n.data); // 13
fm.Write(n.nextNode);
lastNode = thisNode; // 14
thisNode = n.nextNode;
}
fm.deallocate(n.nextNode); // 15
n.nextNode = RWNIL; // 16
fm.SeekTo(lastNode);
fm.Write(n.data);
fm.Write(n.nextNode);
return 0;
} // 17
Here is a line-by-line description of the program:
//1 Include the declarations for the class RWFileManager.
//2 The struct DiskNode is a link in the linked-list. It contains:
//3 the data (an int), and:
//4 the offset to the next link. RWoffset is a typedef to a long int.
//5 This is the constructor for an RWFileManager. It will create a new file, called linklist.dat.
//6 Allocate space on the file to store the offset to the first link. This first allocation is considered special and will be saved by the RWFileManager. It can be retrieved at any time by using the member function start().
//7 Allocate space to store the first link. The member function allocate() returns the offset to this space. Since each DiskNode needs the offset to the next DiskNode, space for the next link must be allocated before the current link is written.
//8 Seek to the position to write the offset to the first link. Note that the offset to this position is returned by the member function start(). Note also that fm has access to public member functions of class RWFile, since class RWFileManager is derived from class RWFile.
//9 Write the offset to the first link.
//10 A loop to read integers and store them in a linked-list.
//11 Allocate space for the next link, storing the offset to it in the nextNode field of this link.
//12 Seek to the proper offset to store this link
//13 Write this link.
//14 Since we allocate the next link before we write the current link, the final link in the list has an offset to an allocated block that is not used. It must be handled as a special case.
//15 First, deallocate the final unused block.
//16 Next, reassign the offset of the final link to be RWNIL. When the list is read, this will indicate the end of the linked list. Finally, rewrite the final link with the correct information.
//17 The destructor for class RWFileManager, which closes the file, will be called here.
Having created the linked-list on disk, how might you read it? Here is a program that reads the list and prints the stored integer field:
 
#include <rw/filemgr.h>
#include <rw/rstream.h>
struct DiskNode {
int data;
RWoffset nextNode;
};
int main(){
RWFileManager fm("linklist.dat"); // 1
fm.SeekTo(fm.start()); // 2
RWoffset next;
fm.Read(next); // 3
DiskNode n;
while (next != RWNIL) { // 4
fm.SeekTo(next); // 5
fm.Read(n.data); // 6
fm.Read(n.nextNode);
std::cout << n.data << "\n"; // 7
next = n.nextNode; // 8
}
return 0;
} // 9
And this is a line-by-line description of the program:
//1 The RWFileManager has been constructed with an old File.
//2 The member function start() returns the offset to the first space ever allocated in the file. In this case, that space will contain an offset to the start of the linked-list.
//3 Read the offset to the first link.
//4 A loop to read through the linked-list and print each entry.
//5 Seek to the next link.
//6 Read the next link.
//7 Print the integer.
//8 Get the offset to the next link.
//9 The destructor for class RWFileManager, which closes the file, will be called here.