内存映射文件处理大文件

点击阅读原文



// 创建文件内核对象,其句柄保存于hFile
HANDLE hFile = CreateFile(“Recv1.zip”,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

// 创建文件映射内核对象,句柄保存于hFileMapping
HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE, 0, 0x4000000, NULL);

// 释放文件内核对象
CloseHandle(hFile);

// 设定大小、偏移量等参数
__int64 qwFileSize = 0x4000000;
__int64 qwFileOffset = 0;
__int64 T = 600 * sinf.dwAllocationGranularity;
DWORD dwBytesInBlock = 1000 * sinf.dwAllocationGranularity;

// 将文件数据映射到进程的地址空间
PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset
>>32), (DWORD)(qwFileOffset&0xFFFFFFFF), dwBytesInBlock);
while(bLoop)
{

// 捕获事件hEvent[0]和事件hEvent[1]
DWORD ret = WaitForMultipleObjects(2, hEvent, FALSE, INFINITE);
ret -= WAIT_OBJECT_0;
switch (ret)
{

// 接收数据事件触发
case 0:

// 从端口接收数据并保存到内存映射文件
nReadLen=syio_Read(port[1], pbFile + qwFileOffset, QueueLen);
qwFileOffset += nReadLen;

// 当数据写满%时,为防数据溢出,需要在其后开辟一新的映射视图
if (qwFileOffset > T)
{
T = qwFileOffset + 600 * sinf.dwAllocationGranularity;UnmapViewOfFile(pbFile);
pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset>>32),
(DWORD)(qwFileOffset&0xFFFFFFFF), dwBytesInBlock);
}
break;

// 终止事件触发
case 1:
bLoop = FALSE;

// 从进程的地址空间撤消文件数据映像
UnmapViewOfFile(pbFile);

// 关闭文件映射对象
CloseHandle(hFileMapping);
break;
}
}…

在终止事件触发处理过程中如果只简单的执行UnmapViewOfFile()和CloseHandle()函数将无法正确标识文件
的实际大小,即如果开辟的内存映射文件为GB,而接收的数据只有GB,那么上述程序执行完后,保存的文
件长度仍是GB。也就是说,在处理完成后还要再次通过内存映射文件的形式将文件恢复到实际大小,下面是
实现此要求的主要代码:

// 创建另外一个文件内核对象
hFile2 = CreateFile(“Recv.zip”, GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ, NULL,CREAT
E_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN,NULL);

// 以实际数据长度创建另外一个文件映射内核对象
hFileMapping2 = CreateFileMapping(hFile2,NULL, PAGE_READWRITE,0,(DWORD)(qwFileOffset&0xFFF
FFFFF),NULL);

// 关闭文件内核对象
CloseHandle(hFile2);

// 将文件数据映射到进程的地址空间
pbFile2 = (PBYTE)MapViewOfFile(hFileMapping2, FILE_MAP_ALL_ACCESS, 0, 0, qwFileOffset);

// 将数据从原来的内存映射文件复制到此内存映射文件
memcpy(pbFile2, pbFile, qwFileOffset);
file:

//从进程的地址空间撤消文件数据映像
UnmapViewOfFile(pbFile);
UnmapViewOfFile(pbFile2);

// 关闭文件映射对象
CloseHandle(hFileMapping);
CloseHandle(hFileMapping2);

// 删除临时文件
DeleteFile(“Recv1.zip”);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值