内存映射文件详解-----C++实现
先不说内存映射文件是什么。贴个代码先,。
#include <iostream>
#include <fcntl.h>
#include <io.h>
#include <afxwin.h>
using namespace std; int main()
{
//开始
//获得文件句柄
HANDLE hFile=CreateFile(
"c:\\test.dat", //文件名
GENERIC_READ|GENERIC_WRITE, //对文件进行读写操作
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING, //打开已存在文件
FILE_ATTRIBUTE_NORMAL,
0); //返回值size_high,size_low分别表示文件大小的高32位/低32位
DWORD size_low,size_high;
size_low= GetFileSize(hFile,&size_high); //创建文件的内存映射文件。
HANDLE hMapFile=CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE, //对映射文件进行读写
size_high,
size_low, //这两个参数共64位,所以支持的最大文件长度为16EB
NULL);
if(hMapFile==INVALID_HANDLE_VALUE)
{
AfxMessageBox("Can't create file mapping.Error%d:\n", GetLastError());
CloseHandle(hFile);
return 0;
} //把文件数据映射到进程的地址空间
void* pvFile=MapViewOfFile(
hMapFile,
FILE_MAP_READ|FILE_MAP_WRITE,
0,
0,
0);
unsigned char *p=(unsigned char*)pvFile; //至此,就获得了外部文件test.dat在内存地址空间的映射,
//下面就可以用指针p"折磨"这个文件了
CString s;
p[size_low-1]='!';
p[size_low-2]='X'; //修改该文件的最后两个字节(文件大小<4GB高32位为0)
s.Format("%s",p);
//读文件的最后3个字节
AfxMessageBox(s); //结束
//UnmapViewOfFile(pvFile); //撤销映射
//CloseHandle(hFile); //关闭文件 return 0;
}
忘小了说,只要你把这几个API函数搞定了,一般的内存映射问题就可以解决了。。但是内存映射文件到底是干嘛的呢?让我们先来思考一个
如果您想读的内容大于系统分配的内存块怎么办?如果您想搜索的字符串刚好超过内存块的边界又该如何处理?对于第一个问题,您也许会说,只要不断地读就不解决了吗。至于第二个问题,您又会说在内存块的边界处做一些特别的处理,譬如放上一些标志位就可以了。原理上确实是行得通,但是这随问题复杂程度加深而显得非常难以处理。其中的第二个问题是有名的边界判断问题,程序中许许多多的错误都是由此引起。想一想,如果我们能够分配一个能够容纳整个文件的大内存块该多好啊,这样这两个问题不都迎刃而解了吗?是的,WIN32的内存映射文件确实允许我们分配一个装得下现实中可能存在的足够大的文件的内存。
利用内存映射文件您可以认为操作系统已经为您把文件全部装入了内存,然后您只要移动文件指针进行读写即可了。这样您甚至不需要调用那些分配、释放内存块和文件输入/输出的API函数,另外您可以把这用作不同的进程之间共享数据的一种办法。运用内存映射文件实际上没有涉及实际的文件操作,它更象为每个进程保留一个看得见的内存空间。至于把内存映射文件当成进程间共享数据的办法来用,则要加倍小心,因为您不得不处理数据的同步问题,否则您的应用程序也许很可能得到过时或错误的数据甚至崩溃。本课中我们将主要讲述内存映射文件,将不涉及进程间的同步。WIN32中的内存映射文件应用非常广泛,譬如:即使是系统的核心模块---PE格式文件装载器也用到了内存映射文件,因为PE格式的文件并不是一次性加载到内存中来的,譬如他它在首次加载时只加载必需加载的部分,而其他部分在用到时再加载,这正好可以利用到内存映射文件的长处。实际中的大多数文件存取都和PE加载器类似,所以您在处理该类问题时也应该充分利用内存映射文件。
内存映射文件本身还是有一些局限性的,譬如一旦您生成了一个内存映射文件,那么您在那个会话期间是不能够改变它的大小的。所以内存映射文件对于只读文件和不会影响其大小的文件操作是非常有用的。当然这并不意味着对于会引起改变其大小的文件操作就一定不能用内存影射文件的方法,您可以事先估计操作后的文件的可能大小,然后生成这么大小一块的内存映射文件,然后文件的长度就可以增长到这么一个大小。
内存映射文件详解-----C++实现的更多相关文章
- Mybatis SQL映射文件详解
Mybatis SQL映射文件详解 mybatis除了有全局配置文件,还有映射文件,在映射文件中可以编写以下的顶级元素标签: cache – 该命名空间的缓存配置. cache-ref – 引用其它命 ...
- Hibernate配置文件和映射文件详解
Hibernate是一个彻底的ORM(Object Relational Mapping,对象关系映射)开源框架. 我们先看一下官方文档所给出的,Hibernate 体系结构的高层视图: 其中PO=P ...
- MyBatis 映射文件详解(六)
MyBatis 配置文件类型 MyBatis配置文件有两种类型,如下: 全局配置文件(如 mybatis-config.xml) Mapper XML 映射文件(如 UserMapper.xml) 上 ...
- Mybatis学习(三)————— 映射文件详解
前面说了全局配置文件中内容的详解,大家应该清楚了,现在来说说这映射文件,这章就对输入映射.输出映射.动态sql这几个知识点进行说明,其中高级映射(一对一,一对多,多对多映射)在下一章进行说明. 一.输 ...
- Mybatis(三) 映射文件详解
前面说了全局配置文件中内容的详解,大家应该清楚了,现在来说说这映射文件,这章就对输入映射.输出映射.动态sql这几个知识点进行说明,其中高级映射(一对一,一对多,多对多映射)在下一章进行说明. 一.输 ...
- MyBatis的SQL语句映射文件详解
SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用 < ...
- hibernate多对多映射文件详解(一)
1.仓库表属性 public class WarehouseNew implements java.io.Serializable { // Fields private static final l ...
- MyBatis 映射文件详解
1. MyBatis 映射文件之<select>标签 <select>用来定义查询操作; "id": 唯一标识符,需要和接口中的方法名一致; paramet ...
- Mybatis的配置文件和映射文件详解
一.Mybatis的全局配置文件 1.SqlMapConfig.xml是mybatis的全局配置文件,配置内容如下: properties(属性) settings(全局配置参数) typeAlias ...
随机推荐
- hdu 1885 Key Task (三维bfs)
题目 之前比赛的一个题, 当时是崔老师做的,今天我自己做了一下.... 还要注意用bfs的时候 有时候并不是最先到达的就是答案,比如HDU 3442 这道题是要求最小的消耗血量伤害,但是并不是最先到 ...
- BZOJ3856: Monster
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3856 题解:怎么乱搞一下都可以把 代码: #include<cstdio> #in ...
- [反汇编练习] 160个CrackMe之011
[反汇编练习] 160个CrackMe之011. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...
- busybox filesystem ifup
/******************************************************************** * busybox filesystem ifup * 声明 ...
- mkswap 把一个分区格式化成为swap交换区
mkswap /dev/sda* //创建此分区为swap 交换分区swapon /dev/sda* //加载交换分区swapoff /dev/sda* //关闭交换分区: 若想要开机自动挂载:vi ...
- 【MySQL for Mac】在Mac终端导入&导出.sql文件
导入 打开终端输入:(前提是已经配置过MySQL环境变量) mysql -u root -p create database name; use name; source 『将.sql文件直接拖拽至终 ...
- 苹果iphone4s完美越狱后破解4g网络方法
苹果iphone4s完美越狱后破解4g网络方法教程 作者:佚名 字体:[增加 减小] 来源:互联网 时间:01-15 10:07:25我要评论 自从港版iPhone5s/c能够破解移动4G网络后, i ...
- innodb buffer pool
add page to flush list buffer pool中的page,有三种状态: l free: 当前page未被使用 l clean: 当前page被使用,对应于数 ...
- FTP文件上传与下载
实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方式:使用jdk中的ftpClie ...
- C# delegate 学习 (练这么久终于悟出来点东东了,继续加油! ^_^)
前言 从事开发工作两年有余了,但还是对Delegate,Event神马的看见就头疼,文章看过无数,自己也练习过好多遍,但到用的时候或者人家换了一种形式之后就又不懂了,哎~智商捉急啊!! 但是,这两天的 ...