【c++】使用Handle实现大文件的读取,需要了解的细节

背景说明:想要读取二进制文件,该文件的字节数上亿。

string或者CString类型的文件路径要转化为LPCSTR型

LPCTSTR即const char
(1)当需要const char
而传入了CString时, C++编译器自动调用 CString重载的操作符 LPCTSTR()来进行隐式的类型转换。
(2)当需要CString , 而传入了 const char* 时(其实 char* 也可以),C++编译器则自动调用CString的构造函数来构造临时的 CString对象。
因此,CString 和 LPCTSTR 基本可以通用。

如何快速获取大文件的字节长度

HANDLE fileHandle = CreateFile(filePath, GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING, 0,0);
int size = GetFileSize(fileHandle , NULL);
//函数参数具体说明见他人博客,此处不过多介绍

如何求结构体类型或其他类型的字节长

int length = sizeof(Road);//我定义的Road结构体
int RoadCount = size / length; //文件写入时,我是以Road结构体为单位写入的,故可以用文件总字节长除以单个Road结构体字节长,求出Road数目。

注意:如果想求vector数组的长度,是不能用sizeof(vector)的,只能用vector.size()。这是由于vector是从堆上分配内存,sizeof(vector)的值取决于vector内部存放的元素的数据类型,与编译器相关,而与元素的数量无关。
因此,在写入二进制文件和读取二进制文件时以X为单位写入或读取,X的类型不能是vector或者不能包含vector。
只能将vector(RoadPoint) coordArr转化成 RoadPoint coordArr[MAXSIZE]。其中RoadPoint是我自己封装的一个结构体如下。

struct RoadPoint
{
	double x;
	double y;
};

代码中的其他结构体如下,只需了解Road和RoadPoint的关系即可看懂后续代码:

struct RoadPoint
{
	double x;
	double y;
};
struct RoadAttribute
{
	char ID[MAXSUBSTRSIZE];
	char Kind_num[5];//注意后续使用判断是位 kindum == '1'
	int Width;
	char PathName[MAXSUBSTRSIZE];
	char SnodeID[MAXSUBSTRSIZE];
	char EnodeID[MAXSUBSTRSIZE];
	char Length[10];
	int RPonitNum;

};

struct Road
{
	struct RoadAttribute RoadAttr;
	RoadPoint coordArr[MAXSIZE];

};

函数功能、返回值意义详细说明(见注释)

	//设置文件路径,CreateFile参数中文件路径的类型为LPCSTR
	//CString转到LPCSTR直接赋值即可
	CString fileroad= (CString)Path + "target.jpg";
	LPCSTR m_road =fileroad; 
	//定义文件映射句柄
	HANDLE fileHandle = CreateFile(m_road, GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING, 0,0);

	//获取文件大小
	int size = GetFileSize(fileHandle, NULL);
	//求出道路总数
	int RoadCount=size/sizeof(Road);

	//定义文件内存映射句柄
	HANDLE handle = CreateFileMapping(fileHandle, NULL, PAGE_READONLY, 0, 0,NULL);
	if(handle == 0)
	{
		printf("CreateFileMapping err\n");
		return ;
	}
	
	//可以把LPVOID理解成一个指针,lp文件的内容要超过50M,不然会程序崩溃
	LPVOID lp =  MapViewOfFile(handle, FILE_MAP_READ, 0, 0 ,0);
	if(lp == NULL)
	{
		DWORD err = GetLastError();
		printf("MapViewOfFile err=%d", err);
		return ;
	}

	//tarDataP是Road* 类型的,已经将其定义为类成员,故不在此处声明
	//分配内存
	tarDataP =(Road *) malloc(size);
	if(tarDataP == NULL)
	{
		printf("malloc err");
		return ;
	}
	//可以直接对LP操作,这里的拷贝只是为了增加时间,避免finish - start为0
	//将字节长度size的lp拷贝到tarDataP中,这里tarDataP和lp是指针
	memcpy_s(tarDataP,size,lp,size);
	//malloc的空间需要手动释放free(tarDataP);释放时间可以修改,可以在完成自己想要进行的功能后释放,也可以在析构函数中释放。
	//此处由于本程序的tarDataP要作为类内成员的值进行后续操作,不在此处释放。

	//释放lp,关闭文件映射句柄
	UnmapViewOfFile(lp);
	CloseHandle(hanle);
	CloseHandle(fileHandle);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值