|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
//主要功能:
|
|
|
// 文件映射类
|
|
|
//
|
|
|
//程序编写: 2008-11-09
|
|
|
//
|
|
|
//
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
namespace NFile64
|
|
|
{
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
// 模块: 内存映射文件用户类
|
|
|
// 说明:
|
|
|
// 利用内存映射文件进行进程之间的内存共享
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
class CFileMappingBase : public CObject
|
|
|
{
|
|
|
DECLARE_DYNAMIC(CFileMappingBase)
|
|
|
|
|
|
public:
|
|
|
CFileMappingBase(void);
|
|
|
virtual ~CFileMappingBase(void);
|
|
|
|
|
|
//在映射时,需要指定数据文件的偏移地址以及待映射的长度。
|
|
|
//其中,文件的偏移地址由64位值来指定,而且必须是操作系统的分配粒度的整数倍
|
|
|
|
|
|
//根据文件名称或其它名称生成一个映射名称,该操作仅是将'\'替换为了'_'
|
|
|
CString CreateMappingName(const CString& sName);
|
|
|
|
|
|
//Create and open/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
//根据文件生成映射,缺省参数只能对文件进行读操作,文件必须存在,
|
|
|
//当文件长度大于4G(32位寻址)时,必须指定偏移地址nOffset,函数内部自动对nOffset取了分配粒度的整数倍
|
|
|
BOOL Open(
|
|
|
LPCTSTR lpszFilePath,
|
|
|
LPCTSTR lpszMappingName,
|
|
|
SIZE_T nMappingSize = 0,
|
|
|
ULONGLONG nOffset = 0,
|
|
|
DWORD dwFileDesiredAccess = GENERIC_READ,
|
|
|
DWORD dwMappingProtection = PAGE_READONLY,
|
|
|
DWORD dwViewDesiredAccess = FILE_MAP_READ
|
|
|
);
|
|
|
|
|
|
//根据文件生成映射,可以对映射文件进行读写操作,文件不存在时生成一个新文件,是对Open函数的包装
|
|
|
BOOL OpenWrite(
|
|
|
LPCTSTR lpszFilePath,
|
|
|
LPCTSTR lpszMappingName,
|
|
|
SIZE_T nMappingSize/* = 0*/,
|
|
|
ULONGLONG nOffset/* = 0*/
|
|
|
);
|
|
|
|
|
|
//根据文件句柄生成映射
|
|
|
BOOL MapFile(
|
|
|
HANDLE hFile,
|
|
|
LPCTSTR lpszMappingName,
|
|
|
SIZE_T nMappingSize = 0,
|
|
|
ULONGLONG nOffset = 0,
|
|
|
DWORD dwMappingProtection = PAGE_READONLY,
|
|
|
DWORD dwViewDesiredAccess = FILE_MAP_READ
|
|
|
);
|
|
|
|
|
|
//直接共享内存映射生成,生成后可以根据映射名称由OpenMapping函数打开已映射的内存
|
|
|
BOOL MapSharedMem(
|
|
|
LPCTSTR lpszMappingName,
|
|
|
SIZE_T nMappingSize, //>0
|
|
|
BOOL* pbAlreadyExisted = NULL,
|
|
|
LPSECURITY_ATTRIBUTES lpsa = NULL,
|
|
|
DWORD dwMappingProtection = PAGE_READWRITE,
|
|
|
DWORD dwViewDesiredAccess = FILE_MAP_ALL_ACCESS
|
|
|
);
|
|
|
|
|
|
//共享内存映射生成,生成后可以根据映射名称由OpenMapping函数打开已映射的内存
|
|
|
//如果物理内存与虚拟内存不够时直接映射会失败,但可以使用硬盘文件映射内存的方法解决(解决大内存映射问题)
|
|
|
BOOL MapFileSharedMem(
|
|
|
LPCTSTR lpszMappingName,
|
|
|
SIZE_T nMappingSize, //>0
|
|
|
BOOL* pbAlreadyExisted = NULL,
|
|
|
LPSECURITY_ATTRIBUTES lpsa = NULL,
|
|
|
DWORD dwMappingProtection = PAGE_READWRITE,
|
|
|
DWORD dwViewDesiredAccess = FILE_MAP_ALL_ACCESS
|
|
|
);
|
|
|
|
|
|
//Open mapping//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
//根据映射名称打开已有的映射
|
|
|
BOOL OpenMapping(
|
|
|
LPCTSTR lpszMappingName,
|
|
|
SIZE_T nMappingSize = 0, //default max. object size
|
|
|
ULONGLONG nOffset = 0, //default map entire file
|
|
|
DWORD dwViewDesiredAccess = FILE_MAP_READ //读写时需要设置为 FILE_MAP_ALL_ACCESS
|
|
|
);
|
|
|
//Remap view///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
//当文件大于4G时,需要映射多次,该函数就是在已打开映射的基础上根据偏移及映射长度重新映射文件视
|
|
|
BOOL OpenNextMapping(
|
|
|
SIZE_T nMappingSize,
|
|
|
ULONGLONG nOffset
|
|
|
);
|
|
|
|
|
|
//Write/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
//将映射中的内容写到磁盘文件中
|
|
|
BOOL Save(
|
|
|
void* lpBaseAddress=NULL, //为空时表示写全部映射
|
|
|
SIZE_T dwNumberOfBytesToFlush=0 //为0时表示从lpBaseAddress地址处写到结尾
|
|
|
);
|
|
|
BOOL SaveAs(LPCTSTR lpFileName); //另存为其它文件
|
|
|
|
|
|
DWORD GetErrorMessage(bool bMessageBox=true); //获得出现问题的ID号,或者报告一个系统错误信息
|
|
|
BOOL IsCanWrite(void); //判断已打开的映射是否支持写操作
|
|
|
BOOL IsOpen(void); //是否打开了一个映射
|
|
|
void Close(void); //关闭映射,同Unmap()
|
|
|
void Unmap(void); //关闭映射
|
|
|
void* GetData(void); //获得映射的开始指针
|
|
|
SIZE_T GetMappingSize(void); //获得映射的大小,当仅是打开映射又没有指定映射大小时为0
|
|
|
ULONGLONG GetOffset(void); //获得映射偏移量
|
|
|
HANDLE GetHandle(void); //获得已映射文件的句柄
|
|
|
ULONGLONG GetPosition(void); //获得当前位置
|
|
|
|
|
|
BOOL Seek(ULONGLONG nOffset, int nOrigin); //设置当前光标位,当相对于开始时nOffset是针对整个文件的偏移量,当为结尾时是针对映射长度的偏移量
|
|
|
SIZE_T Read(char* value, SIZE_T nLength); //从当前光标处读取指定长度字符,存入value中,并根据nLength设置游标新的位置
|
|
|
char* GetCursor(void); //获得游标指针
|
|
|
|
|
|
//Other////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
//动态获取当前操作系统的分配粒度,得到系统的最小内存单位,对于Windows操作系统,分配粒度固定为64KB
|
|
|
DWORD GetSysAllocationGranularity(void);
|
|
|
ULONGLONG GetFileLength(void); //获得被映射文件的长度
|
|
|
CString GetFileName(void); //获得被映射文件的名称
|
|
|
|
|
|
protected:
|
|
|
virtual void AfterMapViewSucceed(void);
|
|
|
char* m_lpCursor;
|
|
|
|
|
|
private:
|
|
|
void* m_pData;
|
|
|
HANDLE m_hMapping; //映射句柄
|
|
|
|
|
|
HANDLE m_hPhysicsFile; //物理文件句柄,当为OpenMapping时为空
|
|
|
ULONGLONG m_nFileLength; //当前被映射文件的长度,当为OpenMapping时为0
|
|
|
CString m_strFileName; //当前被映射的文件名称,当为OpenMapping时为空
|
|
|
|
|
|
DWORD m_dwAlign; //系统的最小内存单位,对于Windows操作系统,分配粒度固定为64KB
|
|
|
ULARGE_INTEGER m_nOffset; //偏移
|
|
|
SIZE_T m_nMappingSize; //映射长度
|
|
|
DWORD m_dwViewDesiredAccess;
|
|
|
|
|
|
BOOL MapView(); //根据设置好的参数获得映射地址
|
|
|
};
|
|
|
|
|
|
};
|
|
|
using namespace NFile64;
|
|
|
|
|
|
ULONGLONG GetFileLength(LPCTSTR lpFileName); //根据文件名称获得文件长度,返回值<0时表示该文件不存在
|
|
|
|
|
|
inline void* CFileMappingBase::GetData(void)
|
|
|
{
|
|
|
return m_pData;
|
|
|
}
|
|
|
|
|
|
inline SIZE_T CFileMappingBase::GetMappingSize(void)
|
|
|
{
|
|
|
return m_nMappingSize;
|
|
|
}
|
|
|
|
|
|
inline HANDLE CFileMappingBase::GetHandle(void)
|
|
|
{
|
|
|
return m_hMapping;
|
|
|
}
|
|
|
|
|
|
inline ULONGLONG CFileMappingBase::GetOffset(void)
|
|
|
{
|
|
|
return m_nOffset.QuadPart;
|
|
|
}
|
|
|
|
|
|
inline char* CFileMappingBase::GetCursor(void)
|
|
|
{
|
|
|
return m_lpCursor;
|
|
|
}
|