当我们需要对大容量文件进行读写的时候,采用CFile类进行读写的话,操作的效率会不高。而且CFile类本身也不是针对大容量文件设计的,所以我们需要提高读写效率的话,需要进行文件映射。
文件映射是指将需要读写的内容映射到内存中去,然后由系统对内存进行操作,写入到文件中去,从而大大的提高读写的速度。不过,这个还是得要和你的存储设备本身的读写效率相挂钩!例如在SD卡上的读写效率会低于在Flash上。
关于文件映射的流程主要是:
1.创建文件对象
m_hFile
=
CreateFileForMapping
(
strDataFile
,
GENERIC_READ
|
GENERIC_WRITE
,
FILE_SHARE_WRITE
,
NULL
,
OPEN_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
|
FILE_FLAG_WRITE_THROUGH
,0);
2.创建文件映射内存的对象
m_hMapFile
=
CreateFileMapping
(
m_hFile
,
NULL
,
PAGE_READWRITE
,0, 0x1400000,
NULL
);
在该部分中,需要我们预先制定我们要生成的文件的大小,例如上面的0x1400000,设定文件最大为20M
3.获取内存映射文件对象的视图
m_pData
= (
BYTE
*)
MapViewOfFile
(
m_hMapFile
,
FILE_MAP_WRITE
,0,0,0x200000);
在这里我们需要制定每次映射的内存大小,例如我的文件生成是20M,但是我每次映射都映射2M,等到不够的时候,再重新映射一次即可。例如:
if
(
m_dataSize
+
nBufLen
>=0x200000)
{
UnmapViewOfFile
(
m_pData
);
m_dataSize
= 0;
m_pData
= (
BYTE
*)
MapViewOfFile
(
m_hMapFile
,
FILE_MAP_WRITE
,0,
m_fileSize
,0x200000);
}
完成了文件视图获取和内存块的申请之后,我们开始利用该快内存对文件进行读写操作,将内容写到缓存中去。而且,文件指针需要设置偏移量,而这个偏移量就是用来定位文件的结尾处,保证数据读写的无缝连接!
memcpy
(
m_pData
+
m_dataSize
,
buf
,
nBufLen
);
在每一次映射的内存块使用完之后需要重新映射的时候,或者需要结束文件的读写的时候,我们需要关闭文件映射。
UnmapViewOfFile
(
m_pData
);
在关闭文件映射之后,如果我们结束了文件的写入操作的时候,我们需要关闭对象句柄,然后就结束了整个文件映射的流程。
SetFilePointer
(
m_hFile
,
m_fileSize
,0,
FILE_BEGIN
);
SetEndOfFile
(
m_hFile
);
UnmapViewOfFile
(
m_pData
);
CloseHandle
(
m_hMapFile
);
CloseHandle
(
m_hFile
);
上面的code中可以看到,我们需要关闭文件句柄,如果我们最后的文件没有达到20M的话,我们需要将多余的部分截断,所以利用SetFilePointer和SetEndOfFile两个函数就可以根据文件的实际大小而截断多余的空闲内存。