内存映射文件(Memory-mapped file)是一种将文件映射到进程的虚拟地址空间的技术。通过这种方式,文件的内容可以直接被当作内存来访问,这样就可以像操作内存一样进行文件读写操作,提高了程序的效率和便捷性。在C语言中,我们可以使用mmap
函数来实现内存映射文件操作。
一、mmap函数概述
在C语言中,mmap
函数定义在头文件<sys/mman.h>
中。它的原型如下:
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
其中:
addr
:指向欲对应的内存起始地址,通常设为NULL,让系统自动选定地址。len
:代表将文件中多大的部分对应到内存。prot
:代表映射区域的保护方式,有以下几种组合:PROT_READ
:映射区域可被读取;PROT_WRITE
:映射区域可被写入;PROT_EXEC
:映射区域可被执行;PROT_NONE
:映射区域不能存取。
flags
:会影响映射区域的各种特性,以下是一些常用的标志:MAP_SHARED
:映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。MAP_PRIVATE
:映射区域的写入操作会产生一个映射文件的复制,即私人的”写入时复制” (copy on write),对此区域作的任何修改都不会写回原来的文件内容。MAP_ANONYMOUS
:建立匿名映射,此时会忽略参数fd
,不涉及文件,而且映射区域无法和其他进程共享。MAP_DENYWRITE
:只允许对应射区域的写入操作,其他对文件直接写入的操作将会被拒绝。MAP_LOCKED
:将映射区域锁定住,这表示该区域不会被置换(swap)。
fd
:文件描述符,通常是调用open
函数打开文件后得到的。offset
:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应。
二、使用mmap进行内存映射文件操作
下面是一个使用mmap
函数进行内存映射文件操作的示例代码:
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDWR); // 打开文件
if (fd == -1) {
perror("open");
return 1;
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
close(fd);
return 1;
}
char *map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
perror("mmap");
close(fd);
return 1;
}
// 修改文件内容
map[0] = 'A';
// 解除映射
if (munmap(map, sb.st_size) == -1) {
perror("munmap");
close(fd);
return 1;
}
// 关闭文件描述符
close(fd);
return 0;
}
在上面的代码中,我们首先使用open
函数打开了一个名为example.txt
的文件。然后,使用fstat
函数获取文件的大小,以便我们可以传递正确的len
参数给mmap
函数。接下来,我们使用mmap
函数将文件内容映射到内存中。在映射后的内存中,我们修改了文件的第一字节,然后使用munmap
函数解除映射关系。最后,我们关闭了文件描述符。
通过使用mmap
函数,我们可以轻松实现内存映射文件操作,提高程序效率。