• 利用mmap和数组方式的存取操作对结构化数据文件进行修改


     1 #include <unistd.h>
     2 #include <stdio.h>
     3 #include <sys/mman.h>
     4 #include <fcntl.h>
     5 #include <stdlib.h>
     6 
     7 typedef struct//定义了一个包含下面两个数据类型的结构体
     8 {
     9     int integer;
    10     char string[24];
    11 } RECORD;//别名为RECORD
    12 
    13 #define NRECORDS (100)//宏定义NRECORDS为(100)
    14 
    15 int main()//主函数
    16 {
    17     RECORD record, * mapped;//分别实现了一个record结构体,和一个指向结构体的指针mapped
    18     int i,f;
    19     FILE * fp;//定义了流指针fp
    20     
    21     fp=fopen("records.dat","w+");//以修改的方式打开文件,并将文件长度截断为0,没有的话就创建
    22     for (i=0;i<NRECORDS; i++)//进入一个条件循环,循环100次
    23     {
    24         record.integer=i;//给结构体的证书部分赋值为i
    25         sprintf(record.string, "RECORD-%d",i);//把格式化的输出传送到指定的地方,-代表左对齐
    26         fwrite(&record, sizeof(record), 1, fp);//把赋值完成的record写入fp中,写入一个指定长度
    27     }
    28     fclose(fp);//关闭打开的流指针
    29     
    30     
    31     
    32     fp=fopen("records.dat","r+");//以写的方式打开文件,并创建文件流fd
    33     fseek(fp,43*sizeof(record),SEEK_SET);//设置文件流的下一次读写的位置,最后一个参数表示绝对位置
    34     fread(&record,sizeof(record), 1, fp);//从fd中读取一个指定长度,到record结构体中
    35     
    36     record.integer=143;            //设置结构体中第一个元素的值为143
    37     sprintf(record.string,"RECORD-%d",record.integer);//同样的把这个值按照左对齐方式传递给结构体的第二个元素
    38     
    39     fseek(fp,43*sizeof(record),SEEK_SET);//重新设置文件流的下一次读写的位置
    40     fwrite(&record,sizeof(record),1,fp);//给文件流写入一个指定长度的record内容
    41     fclose(fp);//关闭打开的文件流
    42     
    43     
    44     
    45     f=open("record.dat",O_RDWR);//使用系统调用open,以读写的方式打开文件,返回文件描述符f
    46     mapped=(RECORD *)mmap(0,NRECORDS*sizeof(record),PROT_READ|PROT_WRITE,MAP_SHARED,f,0);
    47     //创建指向0的内存,长度是100个指定长度,权限是读写内存段,flag取MAP_SHARED表示对内存段的修改保存到
    48     //磁盘文件中,f就是和内存相关的描述符,偏移是0。总体来说是把文件转化为内存中的结构数组
    49     mapped[43].integer=243;//设置结构数组中的第43个元素的第一个值
    50     sprintf(mapped[43].string,"RECORD-%d",mapped[43].integer);//同样按照左对齐方式传递给结构数组第二个元素
    51     
    52     msync((void *)mapped, NRECORDS*sizeof(record),MS_ASYNC);//把内存中的整段的修改按照异步写的方式写回到被映射的文件中
    53     munmap((void *)mapped, NRECORDS*sizeof(record));//全部释放这个内存段
    54     close(f);//关闭打开的文件描述符
    55     
    56     exit(0);
    57 }

    如果是前面不使用mmap程序可以顺利执行,但是加上后面的代码时候,terminal会提示说:

    段错误 (核心已转储)

    参考文献:

    Linux程序设计 Neil Matthew

  • 相关阅读:
    webstorm一键格式化为Eslint标准
    Promise 对象
    ES6类的继承
    RabbitMQ之pika模块
    常见操作
    增量式爬虫
    分布式爬虫(scrapy-redis)
    crawlspider
    scrapy框架学习
    斐波那契数列
  • 原文地址:https://www.cnblogs.com/kongchung/p/4602024.html
Copyright © 2020-2023  润新知