这个例子来自《linux程序设计》,对程序进行了一些注释。具体如下:
#include<unistd.h>
#include<stdio.h>
#include<sys/mman.h> // 包含了关于内存映射的一些函数
#include<fcntl.h>
#include<stdlib.h>
typedef struct {
int integer;
char string[24];
} RECORD;
// 定义结构体变量的数目
#define NRECORDS (100)
int main()
{
RECORD record, *mapped; // record 作用相当于一个缓冲区,把要读或者要写的数据放入其中
int i, f; // i是循环变量,f用于存储open()返回的 文件描述符
FILE *fp;
// 一般的文件操作,生成一个文件,文件内容是循环体中给出的
fp = fopen("record.dat", "w+");
for(i=0; i<NRECORDS; ++i)
{
record.integer = i;
sprintf(record.string, "RECORD-%d",i);
fwrite(&record, sizeof(record),1,fp); // 不管fopen里面设置文件的写入mode,都是以二进制形式写入文件
// 即内存中是什么,文件中就对应什么
}
fclose(fp);
// 打开刚才生成的文件,并修改43的那结构内容为143,同时更新对应的字符串
fp=fopen("record.dat", "r+");
fseek(fp,43*sizeof(record),SEEK_SET);
fread(&record, sizeof(record), 1, fp);
printf("NOW, integer = %d, string = %s\n",record.integer,record.string);// 检验上次是否正确写入
record.integer = 143;
sprintf(record.string, "RECORD-%d", record.integer);
fseek(fp, 43*sizeof(record), SEEK_SET);
fwrite(&record, sizeof(record), 1, fp);
fclose(fp);
// 内存映像函数的示例
f = open("record.dat", O_RDWR);
mapped = (RECORD*)mmap(0, NRECORDS*sizeof(record),
PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
printf("NOW, integer = %d, string = %s\n",
mapped[43].integer,mapped[43].string);// 检验上次是否正确写入
mapped[43].integer = 243;
sprintf(mapped[43].string, "RECORD-%d", mapped[43].integer);
msync((void*)mapped, NRECORDS*sizeof(record),MS_ASYNC); // 同步内存中的数据到相应的文件
munmap((void*)mapped, NRECORDS*sizeof(record)); // 关闭映射
close(f);
return 0;
}
fcntl.h 和 unistd.h的讲解可以参看:http://blog.csdn.net/lyc_daniel/article/details/11740393
mmap() 函数的讲解可以参看:http://blog.csdn.net/dlutbrucezhang/article/details/9080173
msync()中的参数可看:http://www.man7.org/linux/man-pages/man2/msync.2.html