8. 高级文件操作:存储映射

(1)概念:

  存储映射是一个磁盘文件存储空间的一个缓存映射,对缓存数据的读写就相应的完成了文件的读写。

(2)mmap和munmap函数

头文件

#include<sys/types.h>

#include<sys/mman.h>

函数

void* mmap(void* addr, size_t length, int prot, int flags,

                      int fd, off_t offset);

int munmap(void* addr, size_t length);

返回值

mmap成功时返回映射区的起始地址,munmap成功为0,两者出错均返回-1。

功能

mmap:I/O使一个磁盘文件与存储空间中的一个缓存相映射。

Munmap:解除映射。

参数

(1)addr:存储映射区的起始地址,通常设为0,让系统自动分配

(2)length:需要映射的字节数。

(3)prot:保护策略

  ①PROT_READ:映射区可读;②PROT_WRITE:映射区可写;

  ③PROT_EXEC:映射区可执行;④PROT_NONE:映射区不可访问。

(4)flags:

  ①MAP_FIXED:返回地址必须等于addr,不鼓励使用

  ②MAP_SHARED:存储操作立刻修改映射文件内容。

  ③MAP_PRIVATE:存储操作导致创建映射文件的副本,并对副本读写。

(5)offset:映射字节在文件中的偏移量

备注

(1)mmap函数从缓存中获取数据,就相当于读文件中相应的字节。与其类似,将数据存入缓存,则相应字节就自动地写入文件。这样,就可以在不使用read和write的情况下执行I/O

(2)子进程继承父进程的存储映射区

【编程实验】存储映射实现文件写入

//file_map.c

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h> int main(int argc, char* argv[])
{
if(argc < ){
printf("usage: %s file\n",argv[]);
exit();
} int fd = open(argv[], O_RDWR | O_CREAT | O_TRUNC);
if(fd < ){
perror("open error");
exit();
} //定位到文件尾部第26个字节的位置,并创建一个空洞文件
lseek(fd, , SEEK_END);//定位第26个字母Z,所在的位置
write(fd, "0", ); //先写入一个"0",以后会被字母Z覆盖 //对文件的“空洞”区进行存储映射
char* addr = mmap(, //映射区起始地址由系统自动分配
, //映射的字节数
PROT_WRITE,
MAP_SHARED,
fd,
); //从指定的文件偏移量处开始映射 //修改存储映射区的内容(会同步到文件中去)
int i = ;
for(i=; i<; i++)
{
*(addr + i) = 'A' + i; //往空洞区写入26个大写字母
} printf("write success\n"); //解除映射
munmap(addr, );
close(fd); return ;
}

【编程实验】存储映射实现文件的拷贝

//cp_map.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h> int main(int argc, char* argv[])
{
if(argc < ){
printf("usage: %s srcfile, destfile\n", argv[]);
exit();
} int srcfd = open(argv[], O_RDONLY);
if (srcfd < )
{
perror("open error");
exit();
} int dstfd = open(argv[],
O_RDWR | O_CREAT | O_TRUNC, );
if(dstfd < )
{
perror("open error");
exit();
} off_t len = lseek(srcfd, , SEEK_END); //源文件的长度
printf("len: %ld\n", len); //源文件映射到内存
char* addr1 = mmap(, len, PROT_READ, MAP_SHARED, srcfd, );
if(addr1 < )
{
perror("mmap error");
exit();
} //在目标文件中,首先创建一个空洞文件
lseek(dstfd, len-, SEEK_SET);
write(dstfd, "0", ); //这个0会被后面复制而来的文件内容覆盖 //目标文件映射到内存
char* addr2 = mmap(, len, PROT_WRITE, MAP_SHARED, dstfd, );
if(addr2 < )
{
perror("mmap error");
exit();
} //存储映射区的复制,并同步到目标文件中
memcpy(addr2, addr1, len); //拷addr1内容拷到addr2中 printf("copy success!\n"); //撤销映射
munmap(addr1, );
munmap(addr2, ); close(srcfd);
close(dstfd); return ;
}

第3章 文件I/O(7)_高级文件操作:存储映射的更多相关文章

  1. 第17章 内存映射文件(3)_稀疏文件(Sparse File)

    17.8 稀疏调拨的内存映射文件 17.8.1 稀疏文件简介 (1)稀疏文件(Sparse File):指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却一样的占用空间.NTFS文件系统对此 ...

  2. 第3章 文件I/O(6)_高级文件操作:文件锁

    7. 高级文件操作:文件锁 (1)文件锁分类 分类依据 类型 说明 按功能分 共享读锁 文件描述符必须读打开 一个进程上了读锁,共它进程也可以上读锁进行读取 独占写锁 文件描述符必须写打开 一个进程上 ...

  3. mysql学习之路_高级数据操作

    关系 将实体与实体的关系,反应到最终数据表的设计上来,将关系分为三种,一对多,多对多,多对多. 所有关系都是表与表之间的关系. 一对一: 一张表的一条记录一定只对应另外一张表的一条记录,反之亦然. 例 ...

  4. (python数据分析)第03章 Python的数据结构、函数和文件

    本章讨论Python的内置功能,这些功能本书会用到很多.虽然扩展库,比如pandas和Numpy,使处理大数据集很方便,但它们是和Python的内置数据处理工具一同使用的. 我们会从Python最基础 ...

  5. C/C++:提升_头文件的使用

    C/C++:提升_头文件的使用 ◇写在前面 学到现在,很多人编写程序时只会使用一个文件.这样在代码量较小的时候,更利于表达程序,但是随着代码量的逐步增加,程序的思维逻辑不是我们一下子就可以完全理清的, ...

  6. Linux常用命令_(文件权限)

    Linux权限管理: 二.权限管理1.3种基本权限在Linux中,将使用系统资源的人员分为4类:超级用户.文件或目录的属主.属主的同组人和其他人员.超级用户拥有对Linux系统一切操作权限,对 于其他 ...

  7. Asp.Net Web Api 2 实现多文件打包并下载文件示例源码_转

    一篇关于Asp.Net Web Api下载文件的文章,之前我也写过类似的文章,请见:<ASP.NET(C#) Web Api通过文件流下载文件到本地实例>本文以这篇文章的基础,提供了Byt ...

  8. gis空间分析案例_坐标文件高斯投影变换地理处理工具

    gis空间分析案例_坐标文件投影变换地理处理工具 商务科技合作:向日葵,135—4855__4328,xiexiaokui#qq.com 功能: 对文件进行投影变换 特点: 1. 地理处理工具,可以与 ...

  9. ca76a_c++_流文件打开输入输出文件模式p773

    /*ca76a_c++_流文件打开输入输出文件模式利用文件流打开文件进行输入与输出时的选项in.out.app(附加模式).ate((end)文件打开后,定于文件结尾).trunc(裁剪).binar ...

随机推荐

  1. tomcat部署和启动2

    catalina run 启动服务器后,按下CTRL+C,停止服务器,选择"y",退回到正常命令行. catalina stop

  2. Python学习(002)--Python介绍

    一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为AB ...

  3. 如何编写Makefile,一份由浅入深的Makefile全攻略

    本文转载整理自陈浩大大的文章(跟我一起写 Makefile),由于原文内容庞大,故梳理出目录结构以便于学习及查阅参考. 一.概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这 ...

  4. 【Android SDK Manager】SDk国内镜像下载地址

    中国科学院开源协会镜像站地址: IPV4/IPV6: http://mirrors.opencas.cn 端口:80 IPV4/IPV6: http://mirrors.opencas.org 端口: ...

  5. Vue 之axios获取Http响应头

    服务器端:Access-Control-Expose-Headers : 'Authorization' 客户端:res.headers.Authorization 引用链接:https://segm ...

  6. Python高手之路 ------读书有感

    最近忙中偷闲把前些年买的<Python高手之路>翻了出来,大致看完了一遍,其中很多内容并不理解,究其原因应该是实践中的经验不足,而这对于现如今的我仍是难以克服的事情,对此也就只能说是看会了 ...

  7. Qt Quick Hello World hacking

    /********************************************************************************************* * Qt ...

  8. C# 处理DateTime算法,取某月第1天及最后一天

    代码如下所示: /// <summary> /// 取得某月的第一天 /// </summary> /// <param name="datetime" ...

  9. WIFI_认证加密学习_STA_AP_WDS

    2-1.1_15_使用卡1_准备工作及配置内核====================================1.无线网卡连接上路由或AP之后使用上是和有线网卡是一样的,都是socket编程. ...

  10. benthos 通过配置文件配置 stream 说明

    stream 模式,我们也可以通过配置文件进行配置 参考配置文件 input: type: http_server buffer: type: memory pipeline: threads: 4 ...