Windows System Programming Third Edition [Electronic resources]

Johnson M. Hart

نسخه متنی -صفحه : 291/ 78
نمايش فراداده

  • Example: Sequential File Processing with Mapped Files

    The atou program (Program 2-4) illustrates sequential file processing by converting ASCII files to Unicode, doubling the file length. This is an ideal application for memory-mapped files because the most natural way to convert the data is to process it one character at a time without being concerned with file I/O. Appendix C shows that the memory-mapped version can be considerably faster than the file access versions for NTFS files, so the complexity is worthwhile. The book's Web site contains additional performance studies; the highlights are summarized here.

    • Memory-mapping performance improvements apply only to Windows NT and the NTFS.

    • Compared with the best sequential file processing techniques, the performance improvements can be 3:1 or greater.

    • The performance advantage disappears for larger files. In this example, as the input file size approaches about one-third of the physical memory size, normal sequential scanning is preferable. The mapping performance degrades at this point since the input file fills one-third of the memory and the output file, which is twice as long, fills the other two-thirds, forcing parts of the output files to be flushed to disk. Thus, on a 192MB system, mapping performance degenerates for input files longer than 60MB. Most file processing deals with smaller files and can take advantage of file mapping.

    Program 2-4.

    Program 5-3. Asc2UnMM: File Conversion with Memory Mapping
    /* Chapter 5. Asc2UnMM.c: Memory-mapped implementation. */
    #include "EvryThng.h"
    BOOL Asc2Un (LPCTSTR fIn, LPCTSTR fOut, BOOL bFailIfExists)
    {
    HANDLE hIn, hOut, hInMap, hOutMap;
    LPSTR pIn, pInFile;
    LPWSTR pOut, pOutFile;
    DWORD FsLow, dwOut;
    /*   Open and map both the input and output files. */
    hIn = CreateFile (fIn, GENERIC_READ, 0, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    hInMap = CreateFileMapping (hIn, NULL, PAGE_READONLY,
    0, 0, NULL);
    pInFile = MapViewOfFile (hInMap, FILE_MAP_READ, 0, 0, 0);
    dwOut = bFailIfExists ? CREATE_NEW : CREATE_ALWAYS;
    hOut = CreateFile (fOut, GENERIC_READ | GENERIC_WRITE,
    0, NULL, dwOut, FILE_ATTRIBUTE_NORMAL, NULL);
    FsLow = GetFileSize (hIn, NULL); /* Set the map size. */
    hOutMap = CreateFileMapping (hOut, NULL, PAGE_READWRITE,
    0, 2 * FsLow, NULL);
    pOutFile = MapViewOfFile (hOutMap, FILE_MAP_WRITE, 0, 0,
    (SIZE_T)(2 * FsLow));
    /* Convert the mapped file data from ASCII to Unicode. */
    pIn = pInFile;
    pOut = pOutFile;
    while (pIn < pInFile + FsLow)
    {
    *pOut = (WCHAR) *pIn;
    pIn++;
    pOut++;
    }
    UnmapViewOfFile (pOutFile); UnmapViewOfFile (pInFile);
    CloseHandle (hOutMap); CloseHandle (hInMap);
    CloseHandle (hIn); CloseHandle (hOut);
    return TRUE;
    }