C++使用mmap读写文件

一般流程是先创建或打开一个文件,然后使用mmap进行内存映射。

1. 读取文件

// 打开文件
int fd = open("input.txt", O_RDONLY);
// 读取文件长度
int len = lseek(fd,0,SEEK_END);
// 建立内存映射
char *addr = (char *) mmap(NULL, len, PROT_READ, MAP_PRIVATE,fd, 0);
close(fd);
// data用于保存读取的数据
char* data;
// 复制过来
memcpy(data, addr, len);
// 解除映射
munmap(addr, len)

2. 写入文件

假设写入的数据放在char* data中

int len = data.length();
// 打开文件
int fd=open("output.txt", O_RDWR|O_CREAT, 00777);
// lseek将文件指针往后移动file_size-1位
lseek(fd,len-1,SEEK_END);
// 从指针处写入一个空字符;mmap不能扩展文件长度,这里相当于预先给文件长度,准备一个空架子
write(fd, "", 1);
// 使用mmap函数建立内存映射
char* addr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
// 内存映射建立好了,此时可以关闭文件了
close(fd);
// 把data复制到addr里
memcpy(addr, data, len);
// 解除映射
munmap(addr, len)

mmap:文件映射进内存,及window上的对应方法

工作中遇到一个问题,我们的程序内存占用太大,在目标机器上跑着跑着就崩溃了。经过高手提点,可以把某些内存映射到文件中,从而可以省下一些内存。现在做个记录方便以后查阅。

在linux上, 用mmap这个方法:

 int dumpFileDescriptor = open(mmFileName, O_CREAT | O_RDWR, 0755);if(dumpFileDescriptor != -1){void* mappedFileAddress = mmap(NULL,MMAP_ALLOCATOR_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,dumpFileDescriptor,                     0);}// Do something use mappedFileAddress

函数msysc可以保证把数据同步到了磁盘上

1 msync(mappedFileAddress, MMAP_ALLOCATOR_SIZE, MS_SYNC);

等不用的时候,用unmap函数解除映射

1 munmap(mappedFileAddress, MMAP_ALLOCATOR_SIZE);

然后可以用unlink把映射文件删掉,如果需要的话

1 unlink(mmFileName);

同时我在网上搜了一下,windows下面用CreateFileMapping

HANDLE dumpFileDescriptor = CreateFileA(mmFileName,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
HANDLE fileMappingObject = CreateFileMapping(dumpFileDescriptor,NULL,PAGE_READWRITE,0,0,NULL);
void* mappedFileAddress = MapViewOfFile(fileMappingObject,FILE_MAP_ALL_ACCESS,0,0,MMAP_ALLOCATOR_SIZE);// Do something use mappedFileAddress

同步数据到磁盘

1 FlushViewOfFile(mappedFileAddress, MMAP_ALLOCATOR_SIZE);

解除映射

1 UnmapViewOfFile(mappedFileAddress);

Windows上如果想要删除映射文件的话,要先把文件Handle关掉,我一开始不知道这个,怎么删也删不掉。

1 CloseHandle(fileMappingObject);
2 CloseHandle(dumpFileDescriptor);
3 unlink(mmFileName);

两个平台跑起来的效果稍有差别,win32上假如你在heap上申请50M内存(别的什么也不干),把这50M映射了以后可以发现,程序运行时程序占用内存只有几百K,也就是说映射了的内存就跑到磁盘中去了,不占内存空间了,前提是你没有访问这50M空间。Linux上同样的程序,50M还会在内存中,即使你没有访问过它也会在内存里有备份,但是如果你申请的内存很大,比如100M,200M的时候才会释放掉内存空间。我想可能原因是在linux上,只有内存真正不够用时,系统才会把映射到文件中的内存空间释放吧,而windows上只要映射了文件,那么就会释放掉内存,除非你访问它。

下面代码演示:

#include<iostream>
#include <cstringt.h>
#include<vector>
#include<windows.h>
#include <ctime>
using namespace std;int main()
{clock_t start, finish;//------------------------------------------------------内存映射方法;start = clock();//创建或打开文件内核对象;HANDLE fileH = CreateFile("ldFeature.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(fileH == INVALID_HANDLE_VALUE){cout<<"error in CreateFile"<<endl;return -1;}//创建一个文件映射内核对象;HANDLE mapFileH = CreateFileMapping( fileH,NULL,PAGE_READWRITE,0,0,"Resource " );if(mapFileH == NULL){cout<<"error in CreateFileMapping"<<endl;return -1;}//将文件数据映射到进程的地址空间;char * mapH = (char *)MapViewOfFile( mapFileH,FILE_MAP_ALL_ACCESS,0,0,0);if(mapH == NULL){cout<<"error in MapViewOfFile"<<endl;return -1;}//读取数据;char *buf = mapH;double k;int times = 300000*34;for(int i = 1; i <= times; i++){k = atof(buf);buf = strstr(buf+9," ");//cout<<k<<endl;}//关闭句柄;UnmapViewOfFile(mapH);CloseHandle(mapFileH);CloseHandle(fileH);finish = clock();//打印耗时;cout<<"time:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;//------------------------------------------------------传统方法;start = clock();FILE *fp = fopen("ldFeature.txt","r");if(fp == NULL){cout<<"error in fopen"<<endl;return -1;}for(int i = 1 ;i <= times; i++){fscanf(fp,"%lf",&k);}fclose(fp);finish = clock();cout<<"time:"<<(double)(finish - start)/ CLOCKS_PER_SEC<<endl;return 0;
}

大文件读取mmap磁盘映射相关推荐

  1. c#大文件读取和写入数据库

    c#大文件读取和写入数据库(带进度条的源代码) 最近一个项目需要将大文件写入和读取到数据库,觉得可能很多人也需要相关得东西,所以就将代码帖出来 protected int state = 0; //表 ...

  2. python按行读取文件效率高吗_Python按行读取文件的实现方法【小文件和大文件读取】...

    本文实例讲述了Python按行读取文件的实现方法.分享给大家供大家参考,具体如下: 小文件: #coding=utf-8 #author: walker #date: 2013-12-30 #func ...

  3. pandas使用to_feather函数将dataframe保存为feather文件(需要依赖pyarrow包)提升大文件读取效率、pandas使用read_feather函数读取feather文件

    pandas使用to_feather函数将dataframe保存为feather文件(需要依赖pyarrow包)提升大文件读取效率.pandas使用read_feather函数读取feather文件. ...

  4. 西北乱跑娃 --- 易语言大文件读取

    为了读取大文件翻遍了很多网站,都说要使用打开文件属性,让人难以抓住问题解决的核心,值得吐槽的就是易语言收费的特质,去哪里下载以及解决问题都是跌跌斑斑.确实很让人费神,现在把大文件读取写到这里. 一.定 ...

  5. Java 高效大文件 读取 和 写入(一亿行)

    写文件 需求:写入1亿行,7位以内的随机的数字. 首先看成果图,代表没骗大家!!!!! 这个是最终生成的文件,有770多MB .下面用glogg打开预览: 程序打印耗时 7149ms + 923 ms ...

  6. C语言读取大文件的问题 内存映射

    2019独角兽企业重金招聘Python工程师标准>>> [Ref] Windows对文件的读写提供了很丰富的操作手段,如: 1. FILE *fp, fstearm...; (C/C ...

  7. python读取大文件的某行_Python按行读取文件的实现方法【小文件和大文件读取】...

    本文实例讲述了Python按行读取文件的实现方法.分享给大家供大家参考,具体如下: 小文件: #coding=utf-8 #author: walker #date: 2013-12-30 #func ...

  8. php大文件读取excel分割,如何用phpspreadsheet来切割excel大文件(附代码)

    这篇文章给大家介绍的内容是关于如何用phpspreadsheet来切割excel大文件(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 背景: 利用phpspreadshee ...

  9. linux--积累--分析清理服务器大文件--分析清理磁盘空间

    Linux系统中如果发现/目录剩余空间不足,又不新增磁盘挂载,可以使用du和df命令来对找到 不用的大文件,对它们进行删除,从而腾出足够的空间. 详细的操作步骤记录如下: df判断占空间多的目录 使用 ...

  10. php大文件读取和存储,使用PHP读取和解析大文件实战

    21CTO导读:在现在这篇文章中,我们将一起学习处理PHP中的大文件,避免因内存限制而无法使用的方法. 如果你想用PHP处理大文件,PHP提供了一些普通的PHP函数,比如file_get_conten ...

最新文章

  1. python可视化案例书籍推荐_这5款Python可视化神器,总有一款适合你!
  2. kaggle训练模型
  3. 近期论文中的数据集整理0409
  4. QT开发(六十六)——登录对话框的验证机制
  5. WeChat判断是否为微信浏览器访问方法:HTTP_USER_AGENT:MicroMessenger
  6. redis 和 数据库mysql之间的关系
  7. java 累进计费率计算_设计费400万,缴纳所得税100万,如何筹划
  8. stauml工具怎么导入文件_小伙教大家怎么剪辑短视频,1小时就学会添加字幕,值得收藏哦...
  9. jsp文件放在WebRoot下还是WebInfo下
  10. JVM知识点复习(第一次)
  11. AllenNLP安装
  12. 计算机版本低怎么升级,电脑ie浏览器版本过低怎么升级(浏览器版本过低升级步骤)...
  13. There's code using JDBC based datastore and not disposing them和threadLocal多次访问时,有的时候会访问不到
  14. DNSPod x ikuai 联合打造,DNS防御业务正式上线!
  15. 深入NXP蓝牙SDK开发(x)---深挖BLE蓝牙协议栈配对过程(3)_密钥分发
  16. PDPS软件:机器人示教编程与工作站仿真运行
  17. 《数字营销实战》思维导图
  18. MFC 生成 exe文件的图标更改方法
  19. 南加大计算机硕士学制,南加州大学研究生学制几年
  20. 网站忘记密码,如何找回 -- (前提浏览器保存过密码)

热门文章

  1. mysql安装包说明
  2. 单片机烧录文件的几种格式
  3. Android Studio - 安装插件GsonFormat
  4. WiFi密码破解之Aircrack实战演示
  5. 关于拿到一个别人给你已经上架的App源代码时,首先需要干的几个事情
  6. 软件测试文档测试用例,软件测试用例文档模板(带实例)
  7. 使用Animation编辑器编辑动画
  8. 计算机专业技术卷,全国计算机技术与软件专业技术资格(水平)考试1990-2009软件设计师历年真题及答案...
  9. python颜色大全
  10. UE4 下载安装操作步骤