1、目的html
用傳統的IO讀寫大文件,所花時間很長,這每每是程序設計時的瓶頸。使用文件內存映射的方法,將數據分塊讀入內存,再進行處理。這能夠很高效的解決c++讀寫大文件的問題。c++
2、相關命令介紹windows
一、 建立文件(CreateFile),以下:安全
HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
參數解析:app
lpFileName:須要建立或者打開的文件名字函數 dwDesiredAccess:文件的打開方式,GENERIC_READ(只讀), GENERIC_WRITE(只寫), GENERIC_READ | GENERIC_WRITE(讀寫)spa dwShareMode:文件的共享方式,如:FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE.net lpSecurityAttributes:文件的安全屬性,一般爲空設計 dwCreationDisposition:文件的訪問方式,如:CREATE_ALWAYS, CREATE_NEW, OPEN_ALWAYS, OPEN_EXISTING, or TRUNCATE_EXISTING(只能是其中一種,不能組合使用)指針 dwFlagsAndAttributes:文件屬性和標誌 hTemplateFile:模板文件句柄 |
二、 建立文件內存映射(CreateFileMapping),以下:
HANDLE WINAPI CreateFileMapping( _In_ HANDLE hFile, _In_opt_ LPSECURITY_ATTRIBUTES lpAttributes, _In_ DWORD flProtect, _In_ DWORD dwMaximumSizeHigh, _In_ DWORD dwMaximumSizeLow, _In_opt_ LPCTSTR lpName );
參數解析:
hFile:須要建立文件內存映射的文件句柄 lpAttributes:安全屬性指針 flProtect:文件內存映射訪問模式 dwMaximumSizeHigh:內存映射大小的高32位 dwMaximumSizeLow:內存映射大小的低32位 lpName:內存映射的名字 |
3、 得到系統分配粒度(GetSystemInfo),以下:
void WINAPI GetSystemInfo( _Out_ LPSYSTEM_INFO lpSystemInfo )
參數解析:
lpSystemInfo:SYSTEM_INFO結構指針 |
四、 文件內存映射視圖(MapViewOfFile)
LPVOID WINAPI MapViewOfFile( _In_ HANDLE hFileMappingObject, _In_ DWORD dwDesiredAccess, _In_ DWORD dwFileOffsetHigh, _In_ DWORD dwFileOffsetLow, _In_ SIZE_T dwNumberOfBytesToMap );
參數解析:
hFileMappingObject:文件內存映射句柄 dwDesiredAccess:訪問方式,如FILE_MAP_ALL_ACCESS、FILE_MAP_COPY等 dwFileOffsetHigh:文件偏移大小高位 dwFileOffsetLow:文件偏移大小低位 注意:文件偏移必須是系統粒度的整數倍 dwNumberOfBytesToMap:映射多少數據進視圖 |
5、 撤銷文件內存映射視圖(UnmapViewOfFile)
BOOL WINAPI UnmapViewOfFile( _In_ LPCVOID lpBaseAddress );
參數解析:
lpBaseAddress:文件視圖指針 |
3、使用方法
一、 使用CreateFile建立/打開一文件,這個文件對象標識了磁盤上將要用做內存映射文件的文件。
二、 使用CreateFileMapping函數來建立一個文件映射內核對象,告訴系統文件的尺寸以及訪問文件的方式。
三、 使用MapViewOfFile函數負責經過系統的管理而將文件映射對象的所有或部分映射到進程地址空間。
四、 經過UnmapViewOfFile完成從進程的地址空間撤消文件數據的映像、經過CloseHandle關閉前面建立的文件映射對象和文件對象。
4、使用舉例
功能:在一個大文件(文件名BigFile.txt)中,查找一字符串」End」。實現根據字符串"End"將文件截斷的功能。
代碼工程名IOTest.sln:
詳細代碼見BigFileFun.h、BigFileFun.cpp
調用代碼見IOTest.cpp中_tmain函數
詳細代碼(使用的vs2010)見以下連接:
http://yunpan.cn/QDMzDE69qd3Pa
如需訪問密碼,請發郵箱mokimail126@126.com索取
參考文檔:
http://blog.csdn.net/xmnathan/article/details/6072858
http://www.cnblogs.com/yukaizhao/archive/2011/05/18/MapViewOfFile_CreateFileMapping.html
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366548(v=vs.85).aspx