Using a mapped file is strongly recommended for accessing a file that contains legacy data. You can also use mapped files with CommonPoint application system data, though streams are the preferred method.
CAUTION Whenever you map data to memory, you must know the specific format of the data. For example, to map a file of CommonPoint application system data into memory, you need to understand the canonical byte format that the CommonPoint application system uses, or you cannot manipulate the data successfully.
Mapped files provide a reasonable way to access large blocks of single-byte data (such as ASCII) because you can easily treat the data as memory. This means that you can use old-style memory and string manipulation functions (such as C library functions) on the data.
When you use mapped files you must be careful about the byte-ordering and alignment of any primitive larger than a single byte. TStream offers some functions to read and write primitives in non-CommonPoint application system format directly to and from memory. TStream also provides a number of functions to read and write primitives in CommonPoint application system format to and from memory. For more information on TStream, see Chapter 4
, "Communications access."To construct a mapped file, pass TMappedFile::TMappedFile:
// Map aFile into memory and get its length... TMappedFile theMappedFile(aFile); FileSystemEntitySize length = theMappedFile.GetEndOfFile(); // Get the starting address... TMemorySurrogate memory; theMappedFile.GetMemorySurrogate(memory); char* startAddress = (char*) memory.GetStartAddress(); // Walk through the file, printing each character... charcurrentChar; int index = 0; while (index < length) { currentChar = *startAddress++; PrintText(currentChar); index++; }
This code maps a portion of a 1000-byte file into memory, as Figure 14 illustrates.
FileSystemEntitySize start = 250; FileSystemEntitySize end = 750; FileSystemEntitySize length = end-start; TFileRange theRange(start,length); TMappedFile theMappedFile(aFile,MOpenFile::kReadWrite,MOpenFile::kAllowNone,theRange); TMemorySurrogate memory; theMappedFile.GetMemorySurrogate(memory); char* startAddress = (char*) memory.GetStartAddress(); for (int i = 0, i < length, i++) { PrintText(*startAddress++); }
// Initialize our constants... char theChar = 'X'; FileSystemEntitySize length = 1000; // Map aFile into memory and set its length to 1000 (Works if initial file is
// LE 1000 bytes. SetEndOfFile call throws exception if initial file is GT 1000 bytes.) TMappedFile theMappedFile(aFile); theMappedFile.SetEndOfFile(length); // Since we changed the size of the file, we must ensure that we re-map it // using SetRange... TFileRange theRange(0,length);// Select the entire file. TMemorySurrogatememory; theMappedFile.SetRange(range,memory);// Fills in 'memory'. // Get the starting address... char* startAddress = (char*) memory.GetStartAddress(); // Walk through the file, writing an 'X' in each position... for (int index = 0; index < length; index++) { *startAddress++ = theChar; }