mmap

如果要把数据结构写到文件里,并且反复编辑这个文件,可能需要反复设置偏移量并进行读写操作。如果文件需要并发操作就更麻烦了。
一个简单的办法就是用mmap函数吧文件的一个区域映射到一块内存上,把文件读写转化为内存操作,对内存的修改能自动反映到文件上。
如果文件权限允许,mmap还可以实现文件的共享操作。

大致步骤
1 头文件
  1. sys/mman.h

2 打开文件
int fd = open(fname, O_RDWR);

3 将文件的一个区域映射到内存里
test* p1 = mmap(NULL, sizeof(test), PROT_WRITE, MAP_SHARED, fd, 0);

4 操作内存
memcpy(p1, &t1, sizeof(test));

5 释放map
munmap(p1, sizeof(test));


打开文件和释放mmap都比较简单。重点在于映射这步
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset);

参数:
addr 手工指定映射到的地址,如果传入NULL,则自动分配地址。
length 映射的长度
prot 指定希望如何保护映射到的内存。如PROT_EXEC,PROT_READ,PROT_WRITE,字面意思都很好理解。
flags 设置是否是共享内存,对内存的操作是否被其它进程看到。如MAP_SHARED,MAP_PRIVATE。
fd 文件描述符
offset 映射的文件偏移量。只能是pagesize的整数倍。pagesize可以通过sysconf(_SC_PAGESIZE)得到

解除映射
解除映射的时候需要注意的是不能再调用free了。
  1. int munmap(void *addr, size_t length);



完整例子

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>

  8. typedef struct st_test
  9. {
  10.     char c[10];
  11.     int i;
  12.     long l;
  13. } test;

  14. int main()
  15. {
  16.     uint sz = sizeof(test);
  17.     printf("size = %d\n", sz);
  18.     char fname[10] = "testfile";
  19.     int fd = open(fname, O_RDWR);
  20.     char buf[BUFSIZ];
  21.     memset(buf, 'a', BUFSIZ);
  22.     write(fd, buf, BUFSIZ);
  23.     puts("mmap");
  24.     test* p1 = mmap(NULL, sizeof(test), PROT_WRITE, MAP_SHARED, fd, 0);
  25.     if(p1 == MAP_FAILED)
  26.     {
  27.         printf("mmap: %s\n", strerror(errno));
  28.         exit(1);
  29.     }
  30.     test* p2 = mmap(NULL, sizeof(test), PROT_WRITE, MAP_SHARED, fd, 4096);
  31.     if(p2 == MAP_FAILED)
  32.     {
  33.         printf("mmap: %s\n", strerror(errno));
  34.         exit(1);
  35.     }

  36. // printf("%d\n", sysconf(_SC_PAGESIZE));
  37.     printf("%c\n", (char*)p2);
  38.     test t1;
  39.     t1.i = 10;
  40.     strcpy(t1.c, "aaaa");
  41.     t1.l = 10000;
  42.     test t2;
  43.     t2.i = 20;
  44.     strcpy(t2.c, "bbbb");
  45.     t2.l = 20000;

  46.     getchar();
  47.     puts("memcpy p1");
  48.     memcpy(p1, &t1, sz);
  49.     puts("memcpy p2");
  50.     memcpy(p2, &t2, sz);


  51.     printf("%d %s %d\n", p1->i, p1->c, p1->l);
  52.     printf("%d %s %d\n", p2->i, p2->c, p2->l);
  53.     getchar();
  54.     msync(p1, sz, MS_SYNC);
  55.     msync(p2, sz, MS_SYNC);

  56.     munmap(p1, sz);
  57.     munmap(p2, sz);

  58.     return 0;
  59. }



运行效果
[root@server2 mmap]# dmesg >testfile   (创建一个大点的文件)
[root@server2 mmap]# ./a
size = 24
mmap


memcpy p1
memcpy p2
10 aaaa 10000
20 bbbb 20000






来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2120888/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26239116/viewspace-2120888/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值