65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Windows 内存映射文件 (MMF) 的简单文件 I/O

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.24/5 (12投票s)

2009 年 6 月 12 日

CPOL

3分钟阅读

viewsIcon

72486

downloadIcon

3199

一个通用的 C++ 类,用于简单的文件 I/O,就像 CFile 一样。

引言

内存映射文件用于三种不同的目的

  • 在两个不同的进程之间共享数据。
  • 访问磁盘文件上的数据(使用内存映射文件访问磁盘文件上的数据可以屏蔽用户维护缓冲区的细节)。
  • 系统使用 MMF 加载和执行 .exe.dll 文件。

本文演示了使用内存映射文件的简单且通用的磁盘文件 I/O。

CWinMMFIO 是一个通用的 C++ 类,可以用于任何需要文件读取和写入操作的地方。该类封装了 MMF I/O 函数调用的细节。此类非常适合读取跨越数 GB 的大型文件。

已经观察到,与使用 CFilefstream 对象相比,使用 MMF I/O 的读取/写入操作速度更快。

背景

理解和修改代码需要Windows内存管理概念的基础知识。

使用代码

以下是该类的公共接口

/* 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

接口描述

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

以参数 oflags 中定义的访问模式打开文件 strfileOPENFLAGS 枚举器有两个常量,OPN_READOPN_READWRITE。 零字节文件不能被打开进行读取或写入。

bool Close();

取消映射文件的视图,并关闭到文件映射对象和打开文件的打开的 HANDLE

int Read(void* pBuf, quint nCount);

nCount 个字节数读取到缓冲区 pBuf 中;如果 nCount 个字节数不可用,则 Read 从当前位置到文件末尾读取尽可能多的可用字节。

调用者必须确保缓冲区 pBuf 至少是 nCount 个字节宽。 该函数返回实际读取的字节数。 如果当前文件指针位置位于文件末尾且 nCount 大于零,则 Read 返回零。

int Write(void* pBuf, quint nCount);

nCount 个字节数从 pBuf 写入到从当前文件指针位置开始的文件。 每当尝试写入超过文件末尾时,文件大小将按 64KB 的量增加。 此长度由 LONG 内部变量 m_lExtendOnWriteLength 定义。 必要时,文件将恢复到其实际长度。

suint64 Seek(sint64 lOffset, SEEKPOS eseekpos); 

将当前文件指针设置为相对于 SEEKPOS eseekposlOffset 指定的位置。 SEEKPOS 枚举器具有三个常量 SP_BEGINSP_CURSP_ENDSP_BEGIN 指定查找相对于文件开头。 SP_CUR 指定查找相对于当前文件指针。 SP_END 指定查找相对于文件末尾。

suint64 GetPosition();

返回当前文件指针位置

suint64 GetLength();

返回文件的实际长度(以字节为单位)

bool SetLength(const sint64& nLength);

将文件的长度设置为 nLength 字节。 如果无法设置长度,则返回值将为 false。 调用 GetMMFLastError 以获取错误消息。

void GetMMFLastError(rstring& strErr);

当函数失败时,调用 GetMMFLastError 以字符串形式获取错误消息。

关注点

Windows SDK 函数 WriteFile 允许调用者通过根据需要扩展文件大小来写入超过 EOF 的内容。 此功能在内存映射 I/O 中不可直接使用。 为了写入并将文件扩展到当前 EOF 之外,需要取消映射视图并且必须关闭映射对象。 之后,使用 SetEndOfFile 函数扩展文件大小(例如,64K),重新创建映射对象,并重新映射文件。 只要写操作完成,文件必须恢复到其实际长度。

历史

  • 2009 年 6 月 12 日:提交的第一个版本。
© . All rights reserved.