易错点
- 对新创建的文件(文件没有大小)进行映射,会收到bus error的错误
- mmap函数的最后一个参数 offset如果不是4K的整数倍,报错:Invalid argument
mmap(共享映射区)存储映射I/O
-
一个磁盘文件与存储空间中的一个缓冲区相映射,于是当从缓冲区中取数据,就相当于读文件中的相应字节。于此类似,将数据存入缓冲区,则相应的字节就自动写入文件。这样,就可在不适用read和write函数的情况下,使用地址(指针)完成I/O操作。
-
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset):创建映射区
addr :建立映射区的首地址,由Linux内核指定。使用时,直接传递NULL
length :欲创建映射区的大小(不能为0,不能给新创建的文件创建映射区,需要拓展新文件,
可以小于文件大小,可以大于文件的大小(但是毫无意义))
prot :映射区权限PROT_READ、PROT_WRITE、PROT_READ|PROT_WRITE、PROT_NONE、PROT_EXEC
flags :
MAP_SHARED:会将映射区所做的操作反映到物理设备(磁盘)上
MAP_PRIVATE:映射区所做的修改不会反映到物理设备
fd :用来建立映射区的文件描述符
offset :映射文件的偏移(4k的整数倍):MMU帮助完成映射,MMU单位是4K
-
int munmap(void *addr, size_t length):回收映射区
addr :mmap的返回值,映射空间的首地址
length :映射区的大小
例子:给文件创建映射区,再往映射区中写内容,看是否写入磁盘空间
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int fd;
char*p;
fd = open("./my.txt",O_RDWR|O_CREAT,0664);
ftruncate(fd,sizeof("julian\n"));
p = mmap(NULL,sizeof("julian\n"),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
memcpy(p,"julian\n",sizeof("julian\n"));
munmap(p,sizeof("julian\n"));
close(fd);
return 0