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. [转载]三款SDR平台对比:HackRF,bladeRF和USRP

    这篇文章是 Taylor Killian 13年8月发表在自己的博客上的.他对比了三款平价的SDR平台,认为这三款产品将是未来一年中最受欢迎的SDR平台.我觉得这篇文章很有参考价值,简单翻译一份转过来 ...

  2. WEB接口测试之Jmeter接口测试自动化 (二)

    通过逐个录入的方式,好不容易将需要测试几十个接口的300多个测试用例录入sampler-http请求中,固定的测试环境跑起来也还 感觉良好.不料在新服务器环境中跑用例时,问题来了:修改参数维护脚本等成 ...

  3. 重构Tips

    一,重新组织函数1.首先找出局部变量和参数. 1>任何不会被修改的变量都可以当作参数传入.2.去掉临时变量Replace Temp with Query.用查询函数代替临时变量3.Extract ...

  4. JQuery - Tab Control

    http://jqueryui.com/tabs/ <!doctype html> <html lang="en"> <head> <me ...

  5. STM32中TIMx的映射及其通道

    TIMx,通道x,无映射,部分映射,完全映射    TIM1_CH1, PA8,    PE9,    TIM1_CH2, PA9,    PE11    TIM1_CH3, PA10,    PE1 ...

  6. 20155229 2016-2017-2 《Java程序设计》第五周学习总结

    20155229 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 第八章: Java中所有错误都会被打包为对象. 设计错误对象都继承自java.lang.Th ...

  7. 查看图片插件--Viewer(类似于qq和微信聊天 的查看图片)

    Viewer的github地址:https://github.com/fengyuanchen/viewer  下载该插件(在文件夹dist里面) 具有参考价值的几个网站:http://www.dow ...

  8. Django的DateTimeField和DateField

    一.DateField: class DateField(auto_now=False, auto_now_add=False, **options)[source] auto_now:每次保存时,都 ...

  9. 动画Completed事件里获取执行该动画的UI对象

    转:http://www.cnblogs.com/xyq/p/3775732.html 昨天群里有位童鞋提出如何在动画完成事件Completed里获取到执行该动画的UI对象. WPF里动画的Compl ...

  10. Centos下LNMP安装

    安装nginx [root@xuegod64 ~]# yum install -y gcc gcc-c++ autoconf automake zlib zlib-devel openssl open ...