背景说明:想要读取二进制文件,该文件的字节数上亿。
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);