//头文件
#define FILEMAP_MAP_SIZE (64 * 1024 * 1024) //每次映射64M #define FILEMAP_STEP_SIZE (32 * 1024 * 1024) //读大数据的时候每次前移32M
class CFileMap { HANDLE m_hFile; HANDLE m_hMap; int m_Size; //文件长度,以字节计 BYTE* m_Buf; //文件的内存映射区 int m_FilePosAlign; //映射的文件偏移 bool m_ReadOnly; public: CFileMap(); ~CFileMap(); bool ReadOpen(const char* fname); bool WriteOpen(const char* fname, int size, bool is_hidden = false, bool is_sysyem = false); void Close(); BYTE* GetBuf(int pos); int GetSize() { return m_Size; } };
//代码文件
CFileMap::CFileMap() { m_FilePosAlign = 0; m_hFile = 0; m_hMap = 0; m_Size = 0; m_Buf = 0; }
//析构函数,关闭内存映射 CFileMap::~CFileMap() { Close(); }
//只读 bool CFileMap::ReadOpen(const char* fname) { m_ReadOnly = true; m_hFile = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(m_hFile == INVALID_HANDLE_VALUE) { m_hFile = 0; return false; } m_Size = GetFileSize(m_hFile, 0); if(m_Size == INVALID_FILE_SIZE) { CloseHandle(m_hFile); m_Size = 0; m_hFile = 0; return false; } m_hMap = CreateFileMapping(m_hFile, 0, PAGE_READONLY, 0, 0, 0); if(m_hMap == 0) { CloseHandle(m_hFile); m_Size = 0; m_hFile = 0; return false; } return true; }
//只写 bool CFileMap::WriteOpen(const char* fname, int size, bool is_hidden, bool is_sysyem) { m_ReadOnly = false; DWORD attr = FILE_ATTRIBUTE_NORMAL; if(is_hidden) attr |= FILE_ATTRIBUTE_HIDDEN; if(is_sysyem) attr |= FILE_ATTRIBUTE_SYSTEM; m_hFile = CreateFile(fname, GENERIC_READ|GENERIC_WRITE, 0, 0, CREATE_ALWAYS, attr, 0); if(m_hFile == INVALID_HANDLE_VALUE) { m_hFile = 0; return false; } m_hMap = CreateFileMapping(m_hFile, 0, PAGE_READWRITE, 0, size, 0); if(m_hMap == 0) { CloseHandle(m_hFile); m_hFile = 0; return false; } m_Size = size; return true; }
//关闭文件映射 void CFileMap::Close() { if(m_Buf != 0) UnmapViewOfFile(m_Buf); if(m_hMap != 0) CloseHandle(m_hMap); if(m_hFile != 0) CloseHandle(m_hFile);
m_hFile = 0; m_hMap = 0; m_Size = 0; m_Buf = 0; m_FilePosAlign = 0; }
//获得文件的内存区映射地址 BYTE* CFileMap::GetBuf(int pos) { if(pos > m_Size) return 0;
BYTE* addr; //返回的内存地地址 int map_size; //每次映射多长 DWORD access;
if(m_Buf != 0) //已经映射了 { UnmapViewOfFile(m_Buf); m_Buf = 0; }
m_FilePosAlign = pos / FILEMAP_STEP_SIZE * FILEMAP_STEP_SIZE;
if((m_FilePosAlign + FILEMAP_MAP_SIZE) > m_Size) map_size = m_Size - m_FilePosAlign; else map_size = FILEMAP_MAP_SIZE;
if(m_ReadOnly) access = FILE_MAP_READ; else access = FILE_MAP_ALL_ACCESS;
m_Buf = (BYTE*)MapViewOfFile(m_hMap, access, 0, m_FilePosAlign, map_size);
if(m_Buf == 0) { m_FilePosAlign = 0; return 0; } else { addr = m_Buf + (pos - m_FilePosAlign); return addr; } } |