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 str
buf = start;
}
//释放
UnmapViewOfFile(hFile);
CloseHandle(hFileMap);
}
其中的,_get_line 函数
" " 在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 != "
")) ++tmp;
//while(*tmp && (*tmp != 0x0d || *tmp != 0x0a )) ++tmp;
*len = tmp - buf; //
if (*tmp == 0) return NULL;
// skip New-Line char
if (*tmp == 0x0d){ // Windows style New-Line 0x0d 0x0a
tmp += 2;
//assert(*tmp == 0x0a);
}//else Unix style New-Line 0x0a
else{
++tmp;
}
return tmp;
}
用十三万多行来测试,这样按行来处理时,不如getiline速度快。
内存映射的优势还是在于大文件。
fstream.open() 时,由于文件太大,IO一次读不了所有的数据,需要多次IO操作。
而内存映射,并不是将文件加载到内存。内存映射首先申请一段地址空间,并映射到物理存储器,而这里的物理存储器就是文件所在的磁盘,类似虚拟内存(pagefile);
当有需要时,程序不需要先把它加到内存,而是直接从磁盘读取。这样就减少了IO操作。
内存映射的一个优势还在于多个进程之间共享数据。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: React 组件的三种写法总结
- 下一篇: js+php微信扫码支付详细说明+demo
