Creating a mapped file

Mapped files operate differently than file streams. When you open a mapped file, the system takes the file contents on a device and places this in memory, returning a pointer. As you access the file, you walk (or jump) through the data in memory. When you write the data from a mapped file, the system flushes that portion of memory out to the device.


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:

Mapping a file into memory

This example maps a file into memory and steps through each character of the file, printing the contents.

      // 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++;
      }

Using a file range with a mapped file

You can use
TFileRange with a mapped file to specify a range of bytes you want to map into memory. Data mapped in with public visibility can be seen and is persistent; if private visibility is specified, the data is not seen and not persistent.


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++);
      }
This example maps a file into memory given a set range, then walks through the file in memory, replacing each character with "X".

      // 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; }
NOTE Whenever you call SetEndOfFile in a way that grows the file, you must call SetRange with the new length to make the new portion visible. Mapped data cannot be truncated; to truncate data in a mapped file, call SetRange to map a range that does not include the part of the file to be truncated.


[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker