Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

Simple File I/O Using Windows Memory Mapped Files (MMF)

4.24/5 (12 votes)
12 Jun 2009CPOL3 min read 72K   3.2K  
A generic C++ class for simple file I/O, just like CFile.

Introduction

Memory mapped files are used for three different purposes:

  • To share data between two different processes.
  • To access data on a disk file (accessing data on a disk file using memory mapped files shields the user from the details of maintaining a buffer).
  • The system uses MMFs to load and execute .exe and .dll files.

This article demonstrates a simple and generic disk file I/O using memory mapped files.

The class CWinMMFIO is a generic C++ class which can be used wherever file read and write operations are required. The class encapsulates the details of MMF I/O function calls. This class is ideal for reading bigger sized files spanning several giga bytes.

It has been observed that read/write operations are much faster using MMF I/O than using either CFile or fstream objects.

Background

Fundamentals of Windows memory management concepts is necessary to understand and modify the code.

Using the code

Following is the public interface to the class:

C++
/* Construction */
bool Open(const rstring& strfile, OPENFLAGS oflags);
bool Close();
/* I/O */
int Read(void* pBuf, quint nCount);
int Write(void* pBuf, quint nCount);
/* Position */
suint64 Seek(sint64 lOffset, SEEKPOS eseekpos); 
suint64 GetPosition();
/* Length */
suint64 GetLength();
bool SetLength(const sint64& nLength);
/*error*/
void GetMMFLastError(rstring& strErr);scription

Interface description

C++
bool Open(const rstring& strfile, OPENFLAGS oflags);

Opens the file strfile in the access mode defined in the parameter oflags; the OPENFLAGS enumerator has two constants, OPN_READ and OPN_READWRITE. A zero byte file cannot be opened either for reading or writing.

C++
bool Close();

Unmaps the view of the file, and closes open HANDLEs to the file mapping object and the opened file.

C++
int Read(void* pBuf, quint nCount);

Reads nCount number of bytes into the buffer pBuf; if nCount number of bytes are not available, then Read reads as many bytes available from the current position to the end of the file.

The caller must ensure that the buffer pBuf is at least nCount number of bytes wide. The function returns the actual number of bytes read. If the current file pointer position is at the end of the file and nCount is greater than zero, then Read returns zero.

C++
int Write(void* pBuf, quint nCount);

Writes nCount number of bytes from pBuf to the file starting from the current file pointer position. The file size is extended by a quantum of 64KB whenever an attempt is made to write past the end of file. This length is defined by a LONG internal variable m_lExtendOnWriteLength. The file will be restored to its actual length when necessary.

C++
suint64 Seek(sint64 lOffset, SEEKPOS eseekpos); 

Sets the current file pointer to the location specified by lOffset relative to SEEKPOS eseekpos. The SEEKPOS enumerator has three constants SP_BEGIN, SP_CUR, and SP_END. SP_BEGIN specifies that the seek is relative to file beginning. SP_CUR specifies that the seek is relative to the current file pointer. SP_END specifies that the seek is relative to the end of file.

C++
suint64 GetPosition();

Returns the current file pointer position:

C++
suint64 GetLength();

Returns the actual length of the file in bytes:

C++
bool SetLength(const sint64& nLength);

Sets the length of the file to nLength bytes. If the length cannot be set, the return value will be false. Call GetMMFLastError to get the error message.

C++
void GetMMFLastError(rstring& strErr);

Call GetMMFLastError to get the error message in the form of a string whenever a function fails.

Points of interest

The Windows SDK function WriteFile allows the caller to write beyond the EOF by extending the file size as necessary. This facility is not available directly in memory mapped I/O. In order to write and extend the file beyond the current EOF, the view needs to be unmapped and the mapping object must be closed. After this, extend the file size (say by 64K) using the SetEndOfFile function, recreate the mapping object, and remap the file. The file must be restored to its actual length whenever the write operation completes.

History

  • 12 June 09: First version submitted.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)