通用文件操作类的设计
2008-05-17 21:54
211 查看
朱金灿
Windows环境下读写文件一般有下列有下面几种方式:C语言的文件操作函数,如fopen函数等,C++的I/O流库,Win32 API的文件操作函数,如CreateFile()、WriteFile()、ReadFile(),MFC的文件操作类,如CFile和CStdioFile等等。但是在大型的数据文件,上面的文件处理方法是不太适合的。对于大文件的操作一般是以内存映射文件来加以处理的。为此本人以读取著名的遥感图像文件格式pix文件来说明如何应用内存文件映射来设计一个通用的文件操作类。
一.内存文件映射的基本原理
首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式。在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据作为映射到该区域的物理存储器进行提交。由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象。
二.应用内存文件映射的基本思路
由上可知,内存文件映射实际上开辟一段内存空间和文件磁盘空间进行映射,因此操作文件的基本思路就是首先获取这段内存的基地址,然后获取信息结构的偏移量,比如你要获取文件头的信息,实际上就是先取得基地址,然后那个偏移量就是文件头的大小,这个和移动文件指针和文件指针的偏移量原理上是差不多的。
下面我以操作pix文件为例,具体代码如下:
class __declspec(dllexport) CPix : public CObject
CPix::CPix(void)
CPix::~CPix(void)
BOOL CPix::GetMapViewAddress(char* pszFileName)
BOOL CPix::OpenForFileHead(char* pszFileName)
BOOL CPix::OpenForImgHeader(char* pszFileName)
BOOL CPix::Close()
[align=left][/align]
[align=left][/align]
[align=left]总结:[/align]
[align=left]1. 假如要读取其它文件格式,首先肯定是要了解该文件格式,定义相关结构体,然后进行内存文件映射,获取基地址。要读取哪部分信息,实际上就是计算其离基地址的偏移量,然后使用memecpy函数。[/align]
[align=left]2. 因为要读取文件不同部分的信息,所以最好设计为多个open函数以便获取文件不同部分的信息。[/align]
[align=left]3. 必须有close函数来撤销文件数据映像,释放相关内存。[/align]
[align=left] [/align]
[align=left]参考文献:[/align]
[align=left]《VC++中使用内存映射文件处理大文件》作者:中国电波传播研究所 郎锐[/align]
[align=left][/align]
Windows环境下读写文件一般有下列有下面几种方式:C语言的文件操作函数,如fopen函数等,C++的I/O流库,Win32 API的文件操作函数,如CreateFile()、WriteFile()、ReadFile(),MFC的文件操作类,如CFile和CStdioFile等等。但是在大型的数据文件,上面的文件处理方法是不太适合的。对于大文件的操作一般是以内存映射文件来加以处理的。为此本人以读取著名的遥感图像文件格式pix文件来说明如何应用内存文件映射来设计一个通用的文件操作类。
一.内存文件映射的基本原理
首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式。在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据作为映射到该区域的物理存储器进行提交。由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象。
二.应用内存文件映射的基本思路
由上可知,内存文件映射实际上开辟一段内存空间和文件磁盘空间进行映射,因此操作文件的基本思路就是首先获取这段内存的基地址,然后获取信息结构的偏移量,比如你要获取文件头的信息,实际上就是先取得基地址,然后那个偏移量就是文件头的大小,这个和移动文件指针和文件指针的偏移量原理上是差不多的。
下面我以操作pix文件为例,具体代码如下:
class __declspec(dllexport) CPix : public CObject
CPix::CPix(void)
CPix::~CPix(void)
BOOL CPix::GetMapViewAddress(char* pszFileName)
BOOL CPix::OpenForFileHead(char* pszFileName)
BOOL CPix::OpenForImgHeader(char* pszFileName)
BOOL CPix::Close()
[align=left][/align]
[align=left][/align]
[align=left]总结:[/align]
[align=left]1. 假如要读取其它文件格式,首先肯定是要了解该文件格式,定义相关结构体,然后进行内存文件映射,获取基地址。要读取哪部分信息,实际上就是计算其离基地址的偏移量,然后使用memecpy函数。[/align]
[align=left]2. 因为要读取文件不同部分的信息,所以最好设计为多个open函数以便获取文件不同部分的信息。[/align]
[align=left]3. 必须有close函数来撤销文件数据映像,释放相关内存。[/align]
[align=left] [/align]
[align=left]参考文献:[/align]
[align=left]《VC++中使用内存映射文件处理大文件》作者:中国电波传播研究所 郎锐[/align]
[align=left][/align]
相关文章推荐
- 通用文件操作类的设计
- 通用文件操作类的设计
- 通用文件操作类的设计
- 通用 Java 文件上传和下载组件的设计与实现
- 通用 Java 文件上传和下载组件的设计与实现
- asp.net 通用文件操作类
- 机器学习小试(6)使用TensorFlow跑通一个通用增量学习流程-设计配置文件
- 通用 Java 文件上传和下载组件的设计与实现
- C++学习:一个通用ini配置文件操作类
- 通用 Java 文件上传和下载组件的设计与实现
- 通用 Java 文件上传和下载组件的设计与实现
- 通用 Java 文件上传和下载组件的设计与实现
- 通用 Java 文件上传和下载组件的设计与实现
- .Net通用大文件上传类
- Qt5:Qt文件操作类 QFile
- vs2008打开aspx文件时设计界面死机的解决(Visual Studio 2008切换设计视图假死正在安装)
- 设计和实现简单的协议,支持传输文件名和文件内容
- C# ASP.NET 走火入魔通用权限管理系统组件V3.2试用版下载地址【含数据库设计文档、使用手册】
- 设计模式学习之GRASP通用职责分配软件模式
- 文件服务器 之 Samba 文件服务器用户复杂权限模型设计和实现