JadeFileMapping::JadeFileMapping():m_dwSysGran(0),m_hFile(INVALID_HANDLE_VALUE),
m_hMapping(NULL),m_lpDataBase(NULL)
{
SYSTEM_INFO SysInfo = { 0 };
GetSystemInfo(&SysInfo);
m_dwSysGran = SysInfo.dwAllocationGranularity;
}JadeFileMapping::~JadeFileMapping()
{
UnmapViewOfFile(m_lpDataBase);
if(m_hMapping != NULL)
{
CloseHandle(m_hMapping);
m_hMapping = NULL;
}
if(m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
m_dwSysGran = 0;
m_lpDataBase = NULL;
}DWORD JadeFileMapping::CreateFileMapping(LPCTSTR lpFile,DWORD dwRW,DWORD dwProtect,DWORD dwStart,DWORD dwEnd,
DWORD dwBufSize,LPVOID *lpAddress)
{
DWORD dwFileMapStart = 0,dwMapViewSize = 0,dwFileMapSize = 0;
int iViewDelta = 0;
if(m_hMapping != NULL)
return JFMP_E_EXISTING;
if(m_hFile != INVALID_HANDLE_VALUE)
return JFMP_E_OPENNED;
m_hFile = CreateFile(lpFile,dwRW,FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
return GetLastError();
//计算文件映射起始位置
dwFileMapStart = (dwStart/m_dwSysGran)*m_dwSysGran;
//文件映射大小
dwMapViewSize = (dwStart%m_dwSysGran)+dwBufSize;
//文件映射句柄大小
dwFileMapSize = dwStart + dwBufSize;
if( 0 > (iViewDelta = dwStart - dwFileMapStart) )
return JFMP_E_BADSTART;
//建立文件映射句柄
m_hMapping = ::CreateFileMapping(m_hFile,NULL,dwProtect,0,dwFileMapSize,NULL);
if(m_hMapping == NULL)
return GetLastError();
*lpAddress = MapViewOfFile(m_hMapping,FILE_MAP_ALL_ACCESS,0,dwFileMapStart,dwMapViewSize);
if(*lpAddress == NULL)
return GetLastError();
m_lpDataBase = *lpAddress;
*lpAddress = (char*)*lpAddress + iViewDelta;
return 0;
}DWORD JadeFileMapping::CreateFileMappingEx(LPCTSTR lpFile,DWORD dwRW,DWORD dwProtect,DWORD dwStart,
DWORD dwEnd,DWORD dwBufSize,LPVOID *lpAddress,
LPVOID lpBaseAddress)
{
DWORD dwFileMapStart = 0,dwMapViewSize = 0,dwFileMapSize = 0;
int iViewDelta = 0;
if(m_hMapping != NULL)
return JFMP_E_EXISTING;
if(m_hFile != INVALID_HANDLE_VALUE)
return JFMP_E_OPENNED;
m_hFile = CreateFile(lpFile,dwRW,FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
return GetLastError();
//计算文件映射起始位置
dwFileMapStart = (dwStart/m_dwSysGran)*m_dwSysGran;
//文件映射大小
dwMapViewSize = (dwStart%m_dwSysGran)+dwBufSize;
//文件映射句柄大小
dwFileMapSize = dwStart + dwBufSize;
if( 0 > (iViewDelta = dwStart - dwFileMapStart) )
return JFMP_E_BADSTART;
//建立文件映射句柄
m_hMapping = ::CreateFileMapping(m_hFile,NULL,dwProtect,0,dwFileMapSize,NULL);
if(m_hMapping == NULL)
return GetLastError();
*lpAddress = MapViewOfFileEx(m_hMapping,FILE_MAP_ALL_ACCESS,0,dwFileMapStart,dwMapViewSize,
lpBaseAddress);
if(*lpAddress == NULL)
return GetLastError();
m_lpDataBase = *lpAddress;
*lpAddress = (char*)*lpAddress + iViewDelta;
return 0;
}异常处理部分自己加
解决方案 »
- CTreeCtrl选中节点,但显示的却是上一次选中的节点
- 请大侠教:上位机和单片机的通信协议编程问题
- ClistBox 问题
- OPENGL问题(光照球的问题)
- 使用OpenProcess()失败,什么原因??
- 急求~~VC++6.0编译器~~
- 我要实现一个类似VC左边工程树的CDialogBar,但总出问题哪位朋友帮忙看看。分不够还可以加
- 求救!关于c++连接mysql数据库的问题
- 请教各位大虾
- 如何 1控制使远程传输完毕(判断传输完毕), 2 server 将把传来的文件写入数据库
- 求一个直接在屏幕上输出文字的程序,急,在线等
- 请问如何使用ShellExecute打开本程序所在目录的一个文件
也可以用事先预留地址空间的方法,在每次映射前释放空间,映射后再把剩余空间保留起来。非法操作应该是你的代码有问题。
可以自己做一层内存管理。用分块法实现。将整个进程的地址空间划分为若干区域,每个区域只存放固定大小的文件(文件大小不够则RoundUp为该区域分块大小)。
例如,划分为A, B, C三个区域,分别存放大小为(0,1MB], (1MB,4MB], (4MB, 16MB]的文件。例如来了一个3MB的文件,就给他在B区预留并映射4MB的空间,来了个5MB的文件,就给他在C区预留并映射16MB的空间。
该法可以去除外部碎片。但是会存在内部碎片,例如5MB的文件,将要浪费11MB的地址空间。
另外该法也需要在最开始预测各区域的比例。如果进程允许有重启的机会,就好办了。可以利用重启的机会消除地址空间碎片,即重新加载到连续的区域。
或者采用lazy策略,直到地址空间不够装下一个大文件时,才撤销所有映射,重新映射。此法类似.NET的内存垃圾回收策略。
预留空间的方法,在每次Map和Unmap前后都要释放和分配内存,以保持地址空间连续,不被占用,只要确保中间过程没有其它线程分配内存,就不会有问题。不过这种做法不适合于同时交叠多个映射。