mmap的使用
mmap是linux下的CreateFileMapping,用来映射并同步文件。
这样的话,比如我自定义一种文件格式,把它写入到文件中,现在想修改其中的值,就可以用这个函数,把文件映射到内存中
然后用操作数组的方式,来进行文件的同步。如果不用这个函数就得:
1、定义一个结构体
2、定义结构体数组
3、读取文件(w+)
4、修改文件
5、写回文件
这样的话,比如我自定义一种文件格式,把它写入到文件中,现在想修改其中的值,就可以用这个函数,把文件映射到内存中
然后用操作数组的方式,来进行文件的同步。如果不用这个函数就得:
1、定义一个结构体
2、定义结构体数组
3、读取文件(w+)
4、修改文件
5、写回文件
如果用这个函数,就不需要那么麻烦了:
1、定义结构体
2、定义结构体指针
3、打开文件,将文件句柄传递给mmap进行映射,返回的是结构体数组
4、修改并写回
具体的差异体现在回写上。
贴段代码,例子是《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
#define FILENAME ("records.dat")
int main()
{
RECORD record, *mapped;
int i,f;
FILE *fp;
fp = fopen(FILENAME,"w+");
if(!fp)
{
perror("opern file error");
return EXIT_FAILURE;
}
for(i = 0; i < NRECORDS; i++)
{
bzero(&record,sizeof(record));
record.integer = i;
sprintf(record.string,"RECORD-%d",i);
fwrite(&record,sizeof(record),1,fp);
}
fclose(fp);
fp = fopen(FILENAME,"r+");
fseek(fp,43*sizeof(record),SEEK_SET);
fread(&record,sizeof(record),1,fp);
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(FILENAME,O_RDWR);
//以共享模式mmap,详见man mmap
mapped = (RECORD *)mmap(0,NRECORDS * sizeof(record),
PROT_READ | PROT_WRITE,MAP_SHARED,f,0);
//改变其中的值,字符串和数值
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;
}
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
typedef struct
{
int integer;
char string[24];
} RECORD;
#define NRECORDS 100
#define FILENAME ("records.dat")
int main()
{
RECORD record, *mapped;
int i,f;
FILE *fp;
fp = fopen(FILENAME,"w+");
if(!fp)
{
perror("opern file error");
return EXIT_FAILURE;
}
for(i = 0; i < NRECORDS; i++)
{
bzero(&record,sizeof(record));
record.integer = i;
sprintf(record.string,"RECORD-%d",i);
fwrite(&record,sizeof(record),1,fp);
}
fclose(fp);
fp = fopen(FILENAME,"r+");
fseek(fp,43*sizeof(record),SEEK_SET);
fread(&record,sizeof(record),1,fp);
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(FILENAME,O_RDWR);
//以共享模式mmap,详见man mmap
mapped = (RECORD *)mmap(0,NRECORDS * sizeof(record),
PROT_READ | PROT_WRITE,MAP_SHARED,f,0);
//改变其中的值,字符串和数值
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;
}
主要体现mmap功能的部分加了注释,很好理解。
下面的地址讲的比较全面:
http://www.lslnet.com/linux/docs/linux-5064.htm