用内存映射文件来处理大文件

1.使用内存映射文件来处理文件的内容,我们先打开文件并向系统预订一块虚拟地址空间区域。接着让系统把文件的第一个字节映射到该区域的第一个字节。然后就可以访问这块虚拟内存区域,就好像它实际包含了文件一样。


2.这种方法的最大的优点在于让系统为我们处理所有与缓存有关的操作。我们不必再分配任何内存,把文件中的数据载入内存,把数据写回文件、以及释放内存块。


3.而且我们还可以通过只映射文件的一个视图(这个视图只包含文件的一小部分数据)的方式来处理大文件。


下面是代码和详细注释:

#include <iostream>
#include <windows.h>

int main()
{
	SYSTEM_INFO sinf;
	GetSystemInfo(&sinf);

	//打开文件数据
	HANDLE hFile=CreateFile("F:\\S01E01.720p.mkv",GENERIC_READ,FILE_SHARE_READ,NULL,
		OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);

	//创建文件映射对象
	HANDLE hFileMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);

	//记录文件尺寸
	DWORD dwFileSizeHight;
	//GetFileSize参数为文件尺寸高字节的的指针,返回文件尺寸低字节DWORD
	DWORD qwFileSizeLow=GetFileSize(hFile,&dwFileSizeHight);
	__int64 qwFileSize=(((__int64)dwFileSizeHight)<<32)+(__int64)qwFileSizeLow;

	CloseHandle(hFile);//不再需要文件句柄
	
	__int64 qwFileOffset=0;//记录文件的读取位置

	int qwNumOf0s=0;//记录0的个数

	//设定被映射的视图大小为系统分配粒度,一般64k
	DWORD dwByteInBlock=sinf.dwAllocationGranularity;

	while(qwFileSize>0)
	{	
		//如果文件剩余部分小于分配粒度
		if(qwFileSize<dwByteInBlock)
			dwByteInBlock=(DWORD)qwFileSize;

		//映射文件视图
		PBYTE pbFile=(PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_READ,
			(DWORD)(qwFileOffset>>32),				//
			(DWORD)(qwFileOffset & 0xFFFFFFFF),		//指定文件映射的开始字节
			dwByteInBlock);//指定大小

		//统计0的个数
		for(DWORD i=0;i<dwByteInBlock;++i)
			if(0==pbFile[i])
				++qwNumOf0s;

		UnmapViewOfFile(pbFile);

		qwFileOffset+=dwByteInBlock;
		qwFileSize-=dwByteInBlock;
	}

	CloseHandle(hFileMapping);
	std::cout<<"0的个数为:"<<qwNumOf0s<<std::endl;
	return 0;
}

注意:

1.这个算法会映射许多小于或等于64k(系统分配粒度)的视图。

2.MapViewOfFile要求文件的偏移量必须是分配粒度的整数倍。

3.完成算法后,需要注意清理工作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值