在现在的项目中需要用到mmap建立内存映射文件,顺便把存储映射I/O看了一下,这个东西还真是加载索引的良好工具,存储映射I/O可以使一个磁盘文件与存储空间中的一个缓冲区相映射,这样可以从缓冲区中读取数据,就相当于读文件中的相应字节,而当将数据存入缓冲区时,最后相应字节就自动写入文件中。
利用mmap建立内存映射文件一般会分为两条线:写文件,读文件,在分别介绍这两条线之前首先将存储映射I/O的常用函数介绍一下。
一. 存储映射I/O基本函数
(1) mmap函数, 这个函数会告诉内核将一个给定的文件映射到一个存储区域中,其函数原型为:
void* mmap(void *addr,size_t len,int prot,int flags,int fields,off_t off);
其中,参数addr用于指定存储映射区的起始地址,通常设定为0,这表示由系统选择该映射区的起始地址,参数len是指定映射的字节数,参数port指定映射区的方式,如PROT_READ,PROT_WRITE,值得注意的是映射区的保护不能超过文件open模式访问权限。参数flags是设置映射区的属性,一般设为MAP_SHARED,这一标志说明本进程的存储操作相当于文件的write操作,参数fields是指定操作的文件描述符,参数off是要映射字节在文件中的起始偏移量。如果函数调用成功,函数的返回值是存储映射区的起始地址;如果调用失败,则返回MAP_FAILED。
(2) msync函数,这个函数会将存储映射区的修改冲洗到被映射的文件中,其函数原型为:
int msync(void *addr,size_t len,int flags)
其中,参数flags参数设定如何控制冲洗存储区,可以选择MS_ASYNC,这表明是异步操作,函数调用立即返回,而选择MS_SYNC,函数调用则等待写操作完成后才会返回。
(3) munmap函数,这个函数会解除文件和存储映射区之间的映射。
int munmap(caddr_t addr,size_t len)
二. 写入映射缓冲区
当我们想向映射缓冲区中写入数据时,首先需要确定映射文件的大小,在打开文件后,可以利用修改文件大小的函数重新设定文件的大小,接下来就可以对该缓冲区进行写操作。
int fd = open(file_name,O_RDWR|O_CREAT);
ftruncate(fd,size);
mmap(0,size,PROT_WRITE,MAP_SHARED,fd,0);
三.从映射缓冲区读取
当我们想从映射缓冲区中读取数据时,需要利用stat系列函数得到文件大小,进行利用在映射存储区中打开该文件。
int fd = open(file_name,O_RDONLY);
struct stat stat_buf;
fstat(fd,&stat_buf);
void *data = mmap(0,stat_buf.st_size,PROT_READ,
MAP_SHARED,fd,0);