内存映射读取文件实战
Contents
概述
内存映射就是将一个磁盘文件和内存的某个缓冲区相映射。经过映射之后,进程可以像操作普通内存一样来操作文件。这样一来,可以减少对系统调用read
和write
的调用,也就避免了用户态到内核态的频繁切换,降低了系统开销,对于读写大文件时,效率会显著增强。
函数原型
|
|
mmap函数
参数说明:
- 第一个参数是要将文件映射到内存的起始地址。一般该参数传入
NULL
,让操作系统内核来分配。函数返回值就是文件映射到进程空间内存的起始地址。 length
指定了要映射文件到进程内存空间的长度。prot
制定了内存的访问权限。有以下几种参数可选:PROT_NONE
:映射内存区不可访问。PROT_WRITE
:可以向映射内存区写入内容。PROT_READ
:可以向映射内存区读取内容。PROT_EXEC
:映射内存区的内容可以被执行。
flags
:如果由多个进程都映射了同一个文件,这个参数值将会影响进程之间对文件修改的可见性。简单地说,就是如果有一个进程更改了文件内容,另一个进程能不能立刻感知到文件内容的变化。该参数有两个参数可选:MAP_SHARED
:设定该参数后,映射同一文件区域的不同进程会感知到文件的变化。MAP_PRIVATE
:和上一个参数相反,这块共享内存是私有的,其他进程感知不到变化。
fd
参数是要映射文件的文件描述符。也就意味着,要使用内存映射文件,必须先用open
函数打开文件,获得文件描述符。offset
一般设置为0
,代表从文件开头开始映射。
返回值:
mmap
调用成功会返回映射到进程内存空间的地址,否则会返回MAP_FAILED
,该值本质上是(void *)-1
,一次在判断mmap
函数是否调用成功可以利用函数返回值来判断。
munmap函数
munmap
函数可以取消当前进程内存空间中由addr
开始的长度为length
的内存映射。
代码实例
|
|
上述程序将file.h
文件中的内容通过内存映射,复制到了file
文件。需要注意的是,file.h
文件是原本就存在的,但是file
文件是新创建的,所以file
文件的初始大小是0
,如果直接进行映射并写入,那么由于文件大小是0
,系统会报出总线错误。所以在进行映射之前,需要改变新创建的文件的大小。程序中调用了ftruncate
函数,将文件变为和file.h
文件一样大,在进行映射拷贝就不会出错了。
Author louis_tian
LastMod 2020-04-05