c++如何实现超大文件读取

c++如何实现超大文件读取,第1张

1、 创建文件(CreateFile),如下:

HANDLE CreateFile(

LPCTSTR lpFileName,

DWORD dwDesiredAccess,

DWORD dwShareMode,

LPSECURITY_ATTRIBUTES lpSecurityAttributes,

DWORD dwCreationDisposition,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile

)

参数解析:

lpFileName:需要创建或者打开的文件名字

dwDesiredAccess:文件的打开方式,GENERIC_READ(只读), GENERIC_WRITE(只写), GENERIC_READ | GENERIC_WRITE(读写)

dwShareMode:文件的共享方式,如:FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE

lpSecurityAttributes:文件的安全属性,通常为空

dwCreationDisposition:文件的访问方式,如:CREATE_ALWAYS, CREATE_NEW, OPEN_ALWAYS, OPEN_EXISTING, or TRUNCATE_EXISTING(只能是其中一种,不能组合使用)

dwFlagsAndAttributes:文件属性和标志

hTemplateFile:模板文件句柄

2、 创建文件内存映射(CreateFileMapping),如下:

HANDLE WINAPI CreateFileMapping(

_In_ HANDLE hFile,

_In_opt_ LPSECURITY_ATTRIBUTES lpAttributes,

_In_ DWORD flProtect,

_In_ DWORD dwMaximumSizeHigh,

_In_ DWORD dwMaximumSizeLow,

_In_opt_ LPCTSTR lpName

)

参数解析:

hFile:需要创建文件内存映射的文件句柄

lpAttributes:安全属性指针

flProtect:文件内存映射访问模式

dwMaximumSizeHigh:内存映射大小的高32位

dwMaximumSizeLow:内存映射大小的低32位

lpName:内存映射的名字

3、 获得系统分配粒度(GetSystemInfo),如下:

void WINAPI GetSystemInfo(

_Out_ LPSYSTEM_INFO lpSystemInfo

)

参数解析:

lpSystemInfo:SYSTEM_INFO结构指针

4、 文件内存映射视图(MapViewOfFile)

LPVOID WINAPI MapViewOfFile(

_In_ HANDLE hFileMappingObject,

_In_ DWORD dwDesiredAccess,

_In_ DWORD dwFileOffsetHigh,

_In_ DWORD dwFileOffsetLow,

_In_ SIZE_T dwNumberOfBytesToMap

)

参数解析:

hFileMappingObject:文件内存映射句柄

dwDesiredAccess:访问方式,如FILE_MAP_ALL_ACCESS、FILE_MAP_COPY等

dwFileOffsetHigh:文件偏移大小高位

dwFileOffsetLow:文件偏移大小低位

注意:文件偏移必须是系统粒度的整数倍

dwNumberOfBytesToMap:映射多少数据进视图

5、 撤销文件内存映射视图(UnmapViewOfFile)

BOOL WINAPI UnmapViewOfFile(

_In_ LPCVOID lpBaseAddress

)

参数解析:

lpBaseAddress:文件视图指针

三、使用方法

1、 使用CreateFile创建/打开一文件,这个文件对象标识了磁盘上将要用作内存映射文件的文件。

2、 使用CreateFileMapping函数来创建一个文件映射内核对象,告诉系统文件的尺寸以及访问文件的方式。

3、 使用MapViewOfFile函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。

4、 通过UnmapViewOfFile完成从进程的地址空间撤消文件数据的映像、通过CloseHandle关闭前面创建的文件映射对象和文件对象。

四、使用举例

功能:在一个大文件(文件名BigFile.txt)中,查找一字符串”End”。实现根据字符串"End"将文件截断的功能。

代码工程名IOTest.sln:

详细代码见BigFileFun.h、BigFileFun.cpp

调用代码见IOTest.cpp中_tmain函数

#include <stdio.h>

#include <string.h>

#define MAXSIZE 4000000

struct password {

char psw[12]// 密码名称

int counter // 出现次数计数器

}

int Append(struct password a[], int *n, char psw[]) {

int i

for(i = 0i <*n++i) {

if(strcmp(a[i].psw,psw) == 0) {

++a[i].counter

return 2

}

}

if(*n <MAXSIZE) {

strcpy(a[*n].psw,psw)

a[*n].counter = 1

++(*n)

return 1

}

return 0

}

int main() {

struct password a[MAXSIZE]

char psw[12]

int i,n = 0,id

char infilename[] = "indata.txt"

char outfilename[] = "outdata.txt"

FILE *inf,*outf

if((inf = fopen(infilename,"rt")) == NULL) {

printf("不能打开数据文件:%s。\n",infilename)

return 1

}

while(fscanf(inf,"%d %11s",&id,psw) == 2) {

if(Append(a,&n,psw) == 0) break

}

fclose(inf)

if((outf = fopen(outfilename,"wt")) == NULL) {

printf("不能打开数据文件:%s。\n",outfilename)

return 2

}

for(i = 0i <n++i)

fprintf(outf,"%s %d\n",a[i].psw,a[i].counter)

fclose(outf)

return 0

}

估计可能是数组越界,修改如下:

int Append(struct password a[], int *n, char psw[]) {

int i

for(i = 0i <*n &&i <MAXSIZE++i) {

if(strcmp(a[i].psw,psw) == 0) {

++a[i].counter

return 2

}

}

if(*n <MAXSIZE) {

strcpy(a[*n].psw,psw)

a[*n].counter = 1

++(*n)

return 1

}

return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12012084.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存