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. TreeView添加treeView1_NodeMouseClick----多么痛的领悟。。。

    TreeView添加treeView1_NodeMouseClick----多么痛的领悟... 1首先说一点,通过参考代码,已经实现了菜单项自动添加到TreeView控件的树视图了. 2.在移植(菜单 ...

  2. (转)2017年12月宋华教授携IBM中国研究院、猪八戒网、中航信托、33复杂美共同论道智慧供应链金融

    今年10月,国务院发布的<关于积极推进供应链创新与应用的指导意见>,不仅强调了发展服务型制造的重要性,同时也指出要积极稳妥发展供应链金融,推动供应链金融服务实体经济,鼓励商业银行.供应链核 ...

  3. 【java编程】重写HashCode和equals方法

    [一]重写equals方案的规则 equals方法本来的原则 1.类的每个实例本质上都是唯一的. 2.不关心类是否提供了“逻辑相等”的测试功能 3.超类已经覆盖了equals,从超类继承过来的行为对于 ...

  4. JavaScript原型继承工作原理

    原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...

  5. Makefile在内核编译中的使用

    1.一个配置选项选中多个文件 path:drivers/media/i2c/adv748x adv748x-objs := \ adv748x-afe.o \ adv748x-core.o \ adv ...

  6. Oracle RAC Failover 详解

    Oracle  RAC 同时具备HA(High Availiablity) 和LB(LoadBalance). 而其高可用性的基础就是Failover(故障转移). 它指集群中任何一个节点的故障都不会 ...

  7. Oracle 11gR2 rac 的各项服务说明

       安装结束后,会产生一些后台进程来确保集群正常工作并能够与外部通讯.其中的一些有序linux平台的要求需要以root用户权限来启动.比如,网络配置的改动就需要更高的权限.其他后台进程将以grid软 ...

  8. Oracle 实例恢复

    -======================= -- Oracle 实例恢复 --======================= 一.Oracle实例失败 Oracle实例失败多为实例非一致性关闭所 ...

  9. <script>标签里的defer和async属性 区别(待补充)

    defer与async的区别(表格显示): table th:first-of-type { width: 150px; } table th:nth-of-type(2) { } 区别 defer ...

  10. mysql explicit_defaults_for_timestamp参数

    在mysql中:- timestamp列如果没有显式定义为null,默认会被设置为not null属性.(其它的数据类型如果没有显式定义为not null,默认是可以为null的).设置timesta ...