映射文件到内存

参考《Linux高级程序设计》

 

函数mmap()将某个文件的指定内容映射到内存空间中,从而提供不同与一般的普通文件操作方式,进程可以像读写内存一样对普通文件进行操作。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read,write等操作。简单地说,就是把一个文件的内容在内存里做一个映像,加快访问速度。函数声明如下:

1 #include <sys/mman.h>
2 void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset)

此函数将在进程的虚拟地址空间(起始为start,长度为len字节)和与文件描述符fd关联的文件(偏移为offset,长度为length字节)之间建立映射。

第1个参数为映射的特定地址,当然,一般情况下设置为NULL,由系统分配。

第2个参数为映射的文件长度。

第3个参数prot描述映射的内存权限(不得与该文件的打开权限冲突),该参数是一下选项的组合:

PROT_READ: 允许读该内存段

PROT_WRITE: 允许写该内存段

PROT_EXEC: 允许执行该内存段

PROT_NONE: 该内存段不能被访问

第4个参数flags控制程序对该内存段的改变所造成的影响。常用选项如下:

MAP_PRIVATE: 内存段是私有的,对它的修改只在局部范围内有效,其他进程不可见。

MAP_SHARED: 共享映射。某进程对该段内存空间的更新对其他进程来说是可见的,但与之关联的该文件的内容并不会立即更新,要更新文件内容,需要调用msync()和munmap()函数。

这个flags参数还有其他一些值,具体可以查mmap()函数的man手册。

第5个参数为映射的文件描述符。

第6个参数为偏移,即要映射的内容在文件中的起始位置。

 

如果要解除映射,可以调用munmap()函数,相应的修改内容将回写到文件中,此函数声明如下:

1 int munmap(void* start,size_t length)

如果希望立即将更新写入文件中,可以调用msync()函数,声明如下:

1 int msync(const void* start,size_t length,int flags)

start为内存的开始位置,length为长度。flags选项如下:

MS_ASYNC: 请内核尽快将资料写入文件中

MS_SYNC: 在此函数结束返回前将资料写入文件。

MS_INVALIDATE: 让内核自行决定是否写入,仅在特殊状况下使用。

 

以下是映射文件到内存,并打印出来的示例代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <memory.h>
 4 #include <sys/mman.h>
 5 #include <sys/types.h>
 6 #include <sys/stat.h>
 7 #include <fcntl.h>
 8 #include <unistd.h>
 9 using namespace std;
10 
11 int main(int argc,char* argv[])
12 {
13     int fd;
14     char *mapped_mem,*p;
15     int flength=1024;
16     void* start_addr=0;
17     fd=open(argv[1],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);    //打开文件
18     flength=lseek(fd,0,SEEK_END);    //求文件长度 同时文件指针移动到了文件尾
19     cout<<"flength: "<<flength<<endl;
20     lseek(fd,0,SEEK_SET);    //将文件指针设置到文件开始位置
21     mapped_mem=(char*)mmap(start_addr,flength,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);    //执行映射
22     *(mapped_mem+flength)='\0';    //加个\0便于使用%s输出 注意这里,如果上面mmap函数参数没有设置PROT_WRITE,那么这里是不可写的。
23     int len=strlen(mapped_mem);
24     cout<<"len: "<<len<<endl;
25     printf("%s\n",mapped_mem);    //打印内容
26     close(fd);
27     munmap(mapped_mem,flength);    //解除映射
28     return 0;
29 }

 

posted on 2013-01-31 20:33  kkzone  阅读(1914)  评论(0编辑  收藏  举报