Linux下内存映射文件的用法

原创 2012年10月16日 09:23:21
学习了一下Linux下内存映射文件的用法,在这里共享一下自己的收获,希望大家提出宝贵意见,进行交流。
    
        简介:

        内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明:

  • 头文件:
    • <unistd.h>
    • <sys/mman.h>
  • 原型: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offsize);
  • 返回值: 成功则返回映射区起始地址, 失败则返回MAP_FAILED(-1).
  • 参数:
    • addr: 指定映射的起始地址, 通常设为NULL, 由系统指定.
    • length: 将文件的多大长度映射到内存.
    • prot: 映射区的保护方式, 可以是:
      • PROT_EXEC: 映射区可被执行.
      • PROT_READ: 映射区可被读取.
      • PROT_WRITE: 映射区可被写入.
      • PROT_NONE: 映射区不能存取.
    • flags: 映射区的特性, 可以是:
      • MAP_SHARED: 对映射区域的写入数据会复制回文件, 且允许其他映射该文件的进程共享.
      • MAP_PRIVATE: 对映射区域的写入操作会产生一个映射的复制(copy-on-write), 对此区域所做的修改不会写回原文件.
      • 此外还有其他几个flags不很常用, 具体查看linux C函数说明.
    • fd: 由open返回的文件描述符, 代表要映射的文件.
    • offset: 以文件开始处的偏移量, 必须是分页大小的整数倍, 通常为0, 表示从文件头开始映射.

 

    下面说一下内存映射的步骤:

  • 用open系统调用打开文件, 并返回描述符fd.
  • 用mmap建立内存映射, 并返回映射首地址指针start.
  • 对映射(文件)进行各种操作, 显示(printf), 修改(sprintf).
  • 用munmap(void *start, size_t lenght)关闭内存映射.
  • 用close系统调用关闭文件fd.

 

注意事项:

在修改映射的文件时, 只能在原长度上修改, 不能增加文件长度, 因为内存是已经分配好的.

 

        在网上找了一些代码,自己加工之后在Linux下编译通过,可以运行实现相应功能。

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>

int main()
{
    int outfile;
    char*mapped;
    char*ptr;

    if((outfile=open("test.dat",O_RDWR|O_CREAT|O_TRUNC,0640))==-1)
    {
        printf("couldn't open this file!\n");
        exit(254);
    }
    lseek(outfile,1000,SEEK_SET);//把文件指针outfile移到从文件头开始到1000字节处

    if(write(outfile,"\0",1)==-1)//在第1001字节处写入数据"\0"

    {
        printf("error,write failed!\n");
        exit(254);
    }
 //创建内存映像文件,将文件从文件头开始到1000字节处映射到内存,mapped指向该内存的首地址

    mapped=mmap(NULL,1000,PROT_READ|PROT_WRITE,MAP_SHARED,outfile,0);

    if(!mapped)
    {
         printf("error ,write failed!\n");
         exit(254);
    }
    ptr=mapped;
    printf("please enter a number!\n");
    fgets(mapped,80,stdin);//从终端输入一个数字

    printf("your number times two is:%d\n",atoi(mapped)*2);
    //将该数字与2相乘结果打印出来

    sprintf(ptr,"your number timews two is :%d\n",atoi(mapped)*2);//把数据保存到内存中

    msync(ptr,1000,MS_SYNC);//将内存中数据保存到文件中

    munmap(ptr,1000); //撤销内存映像文件


    if(close(outfile))
    {
        printf("possibly serious error,close file failed!\n");
        exit(254);
    }

    return 0;
}

 

Linux下内存映射文件的用法简介

由于项目需要,所以学习了一下Linux下内存映射文件的用法,在这里共享一下自己的收获,希望大家提出宝贵意见,进行交流。              简介:         内存映射文件与虚拟内存有...
  • yasaken
  • yasaken
  • 2012年02月02日 17:08
  • 12958

Linux C 文件内存映射

这次再次讨论文件的操作,只是对象换成了大型文件。 之所以讨论大型文件,是因为无论当今的热点“大数据处理”,还是老牌的搜索引擎,都会涉及到大型文件的处理效率。 比如前一张我们生成了50000...
  • superbfly
  • superbfly
  • 2014年04月13日 13:56
  • 6855

在linux中使用内存映射(mmap)操作文件

在使用内存映射操作文件之前,我们先按照常规的方式来读写文件,这种方式操作如下: 1,打开或创建文件,得到文件描述符, 2,将内存中的数据以一定的格式和顺序写入文件,或者将文件中的数据以一定的格式和顺序...
  • hulele2009
  • hulele2009
  • 2013年11月15日 16:50
  • 8645

Linux的mmap内存映射机制解析

在讲述文件映射的概念时, 不可避免的要牵涉到虚存(SVR 4的VM). 实际上, 文件映射是虚存的中心概念, 文件映射一方面给用户提供了一组措施, 好似用户将文件映射到自己地址空间的某个部分, 使用...
  • zqixiao_09
  • zqixiao_09
  • 2016年04月07日 19:48
  • 7923

linux 下文件操作和内存映射的一个简单例子

这个例子来自《linux程序设计》,对程序进行了一些注释。具体如下: #include #include #include // 包含了关于内存映射的一些函数 #include #include ...
  • cjbct
  • cjbct
  • 2016年12月05日 09:55
  • 1009

Linux C++内存映射方式读写文件

内存映射就是将磁盘上的文件映射到系统内存中,对内存的修改可以同步到对磁盘文件的修改。可以对大数据文件处理,并且可以提高文件的读写速度。 1 2 3...
  • abcd1f2
  • abcd1f2
  • 2017年01月16日 16:44
  • 1002

怎样把文件放在Linux内存里

在Linux中可以将一部分内存mount为分区来使用,通常称之为RamDisk。 RamDisk有三种实现方式: · 第一种就是传统意义上的,可以格式化,然后加载。      这在Linux...
  • shaobingj126
  • shaobingj126
  • 2012年04月10日 14:58
  • 2495

Linux下面文件内容到内存区域的映射

利用mmap(建立内存映射) 相关函数 munmap,open 表头文件 #include #include 定义函数 ...
  • u011046042
  • u011046042
  • 2015年11月13日 09:59
  • 2947

Linux内存映射——mmap

一 mmap系统调用 1.内存映射 所谓的内存映射就是把物理内存映射到进程的地址空间之内,这些应用程序就可以直接使用输入输出的地址空间,从而提高读写的效率。Linux提供了mmap()函数...
  • hustfoxy
  • hustfoxy
  • 2013年03月23日 17:00
  • 20110

Linux下C编程-----IO/文件操作/内存映射 实现简单记录存储(3)

利用linux下的文件内存映射可以实现进程共享数据,我们可以把一个文件映射到虚拟内存中使多个进程进行共享, 到这里我们大概能想到他能应用到的领域 是很广泛的  主要涉及到 mmap  munmap  ...
  • yue7603835
  • yue7603835
  • 2015年02月13日 21:15
  • 2501
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux下内存映射文件的用法
举报原因:
原因补充:

(最多只允许输入30个字)