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. 在C#中如何定义一个变长的结构数组?如果定义好了,如何获得当前数组的长度?

    用ArrayList,他就相当于动态数组,用add方法添加元素,remove删除元素,count计算长度

  2. clipboard.js 实现web端---> 复制到剪切板功能

    package.json 中: 添加clipboard 依赖 "dependencies": { "vue": "^2.2.2", &quo ...

  3. caffe测试mnist问题-error while loading shared libraries

    问题描述 build/examples/mnist/convert_mnist_data.bin: error while loading shared libraries: libcudart.so ...

  4. Unity打安卓包 Android 所有错误解决方案大全(几乎囊括所有打包错误 )

    Unity打包出错解决方案 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...

  5. HDU 4662 MU Puzzle 数论或者水题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4662 题目是问目标串能否由MI得到,我们可以逆向思维,目标串能否反过来处理得到MI,所以,首先排除M ...

  6. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.2 activation-group& dialect& date-effective

    转载至:https://blog.csdn.net/wo541075754/article/details/75511887 activation-group 该属性将若干个规则划分成一个组,统一命名 ...

  7. exec函数簇

    转自:http://www.cppblog.com/prayer/archive/2009/04/15/80077.html 也许有不少读者从本系列文章一推出就开始读,一直到这里还有一个很大的疑惑:既 ...

  8. DataFrame 列运算

    import pandas as pd import StringIO table_buffer = StringIO.StringIO('''a b 2007-01-08 0.786667 270 ...

  9. Elasticsearch 知识点

    Elasticsearch 知识点 table th:first-of-type { width: 200px; } table th:nth-of-type(2) { } 功能 curl命令 运行 ...

  10. Generator 知识点

    Generator 函数的执行过程,其实是将同一个回调函数,反复传入 next 方法的 value 属性. Iterator 接口的 next 方法必须是同步的,只要调用就必须立刻返回值.也就是说,一 ...