【Linux编程】存储映射I/O

【Linux编程】存储映射I/O

大家好,又见面了,我是全栈君。

存储映射I/O使一个磁盘文件与存储空间中的一个缓冲区相映射,对缓冲区的读、写操作就是对文件的读、写操作,从而能够不再使用read、write系统调用。


将文件映射到存储区的函数由mmap完毕,函数原型例如以下:
#include <sys/mman.h>
 
/* 成功返回映射区起始地址,出错返回MAP_FAILED */
void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);

參数说明:
  • addr:指定映射存储区的起始地址,通常为0表示由系统选择起始地址。
  • len:须要映射的字节数。
  • prot:对映射存储区的保护要求,不能超过open文件时的权限。
    • PROT_READ:映射区可读
    • PROT_WRITE:映射区可写
    • PROT_EXEC:映射区可运行
    • PROT_NONE:映射区不可訪问
  • flag:影响映射存储区的属性。
    • MAP_FIXED:返回值必须等于addr,不利于移植。不鼓舞使用。
    • MAP_SHARED:表示存储操作相当于对该文件的write。
    • MAP_PRIVATE:对映射区的存储操作导致创建该映射文件的一个私有副本。
  • filedes:指定要被映射的文件描写叙述符,映射之前须要先打开该文件。
  • off:要映射字节在文件里的起始偏移量。通常为0。

存储映射例如以下所看到的:
【Linux编程】存储映射I/O


測试代码:
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
 
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
 
int main(int argc, char *argv[])
{
    int fdin, fdout;
    void *src, *dst;
    struct stat statbuf;
 
    if (argc != 3)
    {
        printf("usage: %s <fromfile> <tofile>\n", argv[0]);
        return -1;
    }
 
    fdin = open(argv[1], O_RDONLY);
    fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE);
 
    fstat(fdin, &statbuf);
 
    lseek(fdout, statbuf.st_size - 1, SEEK_SET);
    write(fdout, " ", 1);   /* lseek偏移量大于文件长度时。写操作将加长文件 */
 
    src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0);
    dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0);
 
    memcpy(dst, src, statbuf.st_size);  /* 数据复制 */
 
    munmap(src, statbuf.st_size);
    munmap(dst, statbuf.st_size);
 
    return 0;
}

此函数实现了文件内容之间的拷贝。

lseek + write的组合操作使得目标文件的大小添加到和源文件大小同样。由于当lseek设置的文件偏移量大于文件当前长度时。下一个写操作将会使文件增大。假设没有对目标文件扩大。那么进程会接收到SIGBUS信号。表示存储区中有地址无法映射到文件里。


mmap实际上是将包括文件内容的内核缓冲区映射到应用程序地址空间,然后用memcpy直接进行数据的拷贝。其优势在于避免了类似read、write系统调用,在内核空间和用户空间之间的数据传递。

參考:
《unix环境高级编程》 P390-P395.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116472.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • MFC的图片按钮

    MFC的图片按钮

    2021年8月31日
    49
  • meshgrid用法「建议收藏」

    meshgrid用法「建议收藏」1、meshgrid函数用两个坐标轴上的点在平面上画格。用法:  [X,Y]=meshgrid(x,y)  [X,Y]=meshgrid(x)与[X,Y]=meshgrid(x,x)是等同的  [X,Y,Z]=meshgrid(x,y,z)生成三维数组,可用来计算三变量的函数和绘制三维立体图    例如例题1:  x=-3:1:3;y=-2:1:2;  [X

    2022年6月10日
    65
  • java中垃圾回收机制_垃圾回收机制算法

    java中垃圾回收机制_垃圾回收机制算法一、如何确定某个对象是“垃圾”?这一小节先了解一个最基本的问题:如果确定某个对象是“垃圾”?既然垃圾收集器的任务是回收垃圾对象所占的空间供新的对象使用,那么垃圾收集器如何确定某个对象是“垃圾”?通过什么方法判断一个对象可以被回收了。在java中是通过引用来和对象进行关联的,也就是说如果要操作对象,必须通过引用来进行。那么很显然一个简单的办法就是通过引用计数来判断一个对象是否可以被回收。不失…

    2022年10月13日
    2
  • Ubuntu安装GCC5/7/9/10/11「建议收藏」

    Ubuntu安装GCC5/7/9/10/11「建议收藏」为了使用C++14/17的新特性,我们难免要升级下自己的GCC版本,同时还要保证自己新安装的GCC生效,并且和原GCC共存。安装GCC-5.0sudoadd-apt-repositoryppa:ubuntu-toolchain-r/testsudoapt-getupdatesudoapt-getinstallgcc-5g++-5sudoupdate-alte…

    2022年7月24日
    24
  • java 读音_java怎么读?[通俗易懂]

    java 读音_java怎么读?[通俗易懂]展开全部US/ˈdʒɑː.və/;UK/ˈdʒɑː.və/。【N-UNCOUNT】Java语言(一种计算机语言,尤用于创建网站)62616964757a686964616fe59b9ee7ad9431333366306461Javaisacomputerprogramminglanguage.Itisusedespeciallyincreatingwebsites.例…

    2022年7月7日
    39
  • 大学生在线四史脚本

    大学生在线四史脚本中国大学生在线脚本无python环境(博主推荐)使用教程软件下载有Python环境编译环境源码分享无python环境(博主推荐)使用教程无Python环境下载可执行文件,将题库.csv与main.exe置于同一文件夹,直接运行即可.uid获取方式:关注公众号:云享科技毒瘤,在菜单栏【四史学习】–>【uid获取】–>【阅读全文】即可查看自己的uid。软件下载公众号:云享科技毒瘤长按二维码关注我们,查看历史文章即可下载声明:1.云享科技毒瘤提供的所有下载文件均在网络收集,请于

    2022年6月14日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号