欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > c/c++ >内容正文

c/c++

c++ 利用内存映射读取大文件

发布时间:2025/3/21 c/c++ 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 c++ 利用内存映射读取大文件 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

由于用到的txt存放的数据有几十万行,用getline来读取文件非常慢,搜索了一下可以来优化读取文件的方法。

据说用内存映射读取文件速度快,试了一下,但是发现要分行处理数据时,速度还是挺慢的。

有关内存映射的介绍,参考别人博客。

http://blog.csdn.net/wcyoot/article/details/7363393

/ ///创建镜像文件来读取文件,提高速度 /// void useMapFileReadText(){HANDLE hFile = NULL, hFileMap = NULL;char * lpbMapAddress = NULL;int nFileSize = 0, nLeftSize = 0;if(hFile == NULL){hFile = CreateFile("data.txt", GENERIC_READ, 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if(hFile == INVALID_HANDLE_VALUE){printf("打开文件失败");}}if(hFileMap == NULL){hFileMap=CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);if(hFileMap==NULL){OutputDebugString("文件镜像句柄创建失败!");CloseHandle(hFile);}}if(lpbMapAddress == NULL){lpbMapAddress = (char *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);if(lpbMapAddress == NULL){OutputDebugString("内存映射文件失败!");CloseHandle(hFileMap);CloseHandle(hFile);} }const char* buf = lpbMapAddress;const char* start = lpbMapAddress;int len;while(start != NULL){start = _get_line(buf, &len);string str(buf,len);//do something with strbuf = start;}//释放UnmapViewOfFile(hFile); CloseHandle(hFileMap); }



其中的,_get_line 函数

'\n' 在windows中为0x0d 0x0a 占两个字符,在linux系统中为0x0a占一个字符。

//buf:从当前地址开始搜索。 //len: 存放该行的字符串长度,不包含回车换行符。 //返回值:下一次搜索开始的地址.如果到达文件尾,则返回NULL const char* _get_line(const char* buf, int* len) {const char* tmp = buf;while(*tmp && (*tmp != 0x0d && *tmp != 0x0a && *tmp != '\n')) ++tmp;//while(*tmp && (*tmp != 0x0d || *tmp != 0x0a )) ++tmp;*len = tmp - buf; //if (*tmp == 0) return NULL;// skip New-Line charif (*tmp == 0x0d){ // Windows style New-Line 0x0d 0x0atmp += 2;//assert(*tmp == 0x0a);}//else Unix style New-Line 0x0aelse{++tmp;}return tmp; }


用十三万多行来测试,这样按行来处理时,不如getiline速度快。

内存映射的优势还是在于大文件。

fstream.open() 时,由于文件太大,IO一次读不了所有的数据,需要多次IO操作。

而内存映射,并不是将文件加载到内存。内存映射首先申请一段地址空间,并映射到物理存储器,而这里的物理存储器就是文件所在的磁盘,类似虚拟内存(pagefile);
当有需要时,程序不需要先把它加到内存,而是直接从磁盘读取。这样就减少了IO操作。


 内存映射的一个优势还在于多个进程之间共享数据。 

总结

以上是生活随笔为你收集整理的c++ 利用内存映射读取大文件的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。