问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

内存映射文件的应用示例

发布网友 发布时间:2022-05-23 07:39

我来回答

1个回答

热心网友 时间:2023-10-16 23:28

下面结合一个具体的实例来进一步讲述内存映射文件的使用方法。该实例从端口接收数据,并实时将其存放于磁盘,由于数据量大(几十GB),在此选用内存映射文件进行处理。下面给出的是位于工作线程MainProc中的部分主要代码,该线程自程序运行时启动,当端口有数据到达时将会发出事件hEvent[0],WaitForMultipleObjects()函数等待到该事件发生后将接收到的数据保存到磁盘,如果终止接收将发出事件hEvent[1],事件处理过程将负责完成资源的释放和文件的关闭等工作。下面给出此线程处理函数的具体实现过程:
// 创建文件内核对象,其句柄保存于hFile
HANDLE hFile = CreateFile(Recv1.zip,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
// 创建文件映射内核对象,句柄保存于hFileMapping
HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0x4000000,NULL);
// 释放文件内核对象
CloseHandle(hFile);
// 设定大小、偏移量等参数 // 尽量把文件设置大一些, 如果写的数据超过,设定的值,再次映射文件会报错 getlasterror = 183;
__int64 qwFileSize = 0x4000000;
__int64 qwFileOffset = 0;
__int64 T = 600 * sinf.dwAllocationGranularity;
DWORD dwBytesInBlock = 1000 * sinf.dwAllocationGranularity;
// 将文件数据映射到进程的地址空间
PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset>>32),(DWORD)(qwFileOffset&0xFFFFFFFF),dwBytesInBlock);
while(bLoop)
{
// 捕获事件hEvent[0]和事件hEvent[1]
DWORD ret = WaitForMultipleObjects(2,hEvent,FALSE,INFINITE);
ret -= WAIT_OBJECT_0;
switch (ret)
{
// 接收数据事件触发
case 0:
// 从端口接收数据并保存到内存映射文件
nReadLen=syio_Read(port[1],pbFile + qwFileOffset,QueueLen);
qwFileOffset += nReadLen;
// 当数据写满60%时,为防数据溢出,需要在其后开辟一新的映射视图
if (qwFileOffset > T)
{
T = qwFileOffset + 600 * sinf.dwAllocationGranularity;UnmapViewOfFile(pbFile);
pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset>>32),(DWORD)(qwFileOffset&0xFFFFFFFF),dwBytesInBlock);
}
break;
// 终止事件触发
case 1:
bLoop = FALSE;
// 从进程的地址空间撤消文件数据映像
UnmapViewOfFile(pbFile);
// 关闭文件映射对象
CloseHandle(hFileMapping);
break;
}
}…
在终止事件触发处理过程中如果只简单的执行UnmapViewOfFile()和CloseHandle()函数将无法正确标识文件的实际大小,即如果开辟的内存映射文件为30GB,而接收的数据只有14GB,那么上述程序执行完后,保存的文件长度仍是30GB。也就是说,在处理完成后还要再次通过内存映射文件的形式将文件恢复到实际大小,下面是实现此要求的主要代码:
// 创建另外一个文件内核对象
hFile2 = CreateFile(Recv.zip,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
// 以实际数据长度创建另外一个文件映射内核对象
hFileMapping2 = CreateFileMapping(hFile2,NULL,PAGE_READWRITE,0,(DWORD)(qwFileOffset&0xFFFFFFFF),NULL);
// 关闭文件内核对象
CloseHandle(hFile2);
// 将文件数据映射到进程的地址空间
pbFile2 = (PBYTE)MapViewOfFile(hFileMapping2,FILE_MAP_ALL_ACCESS,0,0,qwFileOffset);
// 将数据从原来的内存映射文件复制到此内存映射文件
memcpy(pbFile2,pbFile,qwFileOffset);
file:
//从进程的地址空间撤消文件数据映像
UnmapViewOfFile(pbFile);
UnmapViewOfFile(pbFile2);
// 关闭文件映射对象
CloseHandle(hFileMapping);
CloseHandle(hFileMapping2);
// 删除临时文件
DeleteFile(Recv1.zip);

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
八月中国最凉快的地方 八月份哪里最凉快,去哪旅游好?美丽的地方 乱字同韵字是什么意思 华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 头文件的示例 文件的绝对路径 示例 锻造轮毂是由什么材质组成 铝合金压铸件(材料为A356)表面能阳极氧化吗?如不能,为什么? log文件的示例 铝合金型号有什么含义没?哪些的含铝,含硅较少?哪些做压铸表面本色氧化效果更好?例如A356,A380。谢谢 bcp文件的示例 A356材料能用铝合金压铸机压铸吗 A356铝合金压铸工艺要注意什么 轮毂材质 日本一般社员一个月的工资是多少? 日本打工的工资一小时多少 去日本打工最低工资是多少钱一个月 东京地区劳动法最低工资是多少钱一个月 日本人最低工资是多少一个月? 日本现在各个县的最低工资是多少了每小时? 丹麦音箱 劳动节我们应该怎么做?劳动节我们可以做些什么 足玺创始人对于足贴材料选择严格吗? 各种bl小说,有没有推荐的~~~ java 创建文件的实例 并写入信息 我用游标卡尺测量一个孔的内径,孔是有螺纹的,经测量孔的内径是14,现在我要配一个螺栓,螺栓我怎么选择 游标卡尺量内径是多少? excel表格中,一个大的单元格中,字是水平居中,垂直居中,想要写好几行,怎么弄? 什么是科学术语? 什么叫科学名词 什么是科技术语 举一些例子? 关于科学术语 四年级下册第七课科技术语的意思 我一个朋友跟我说了他的心里话,这表明了什么? 领导说不要行捧杀之事该怎样回复? 什么叫科学术语 职场上,同事故意在领导面前捧杀你,你应该如何应对? 以《捧杀》为题的作文?速度点!!! 科学名词是什么 通过影视题材将咏春拳捧高,会造成捧杀的后果吗? 曹雪芹把薛宝钗称做山中高士晶莹雪,这个称呼究竟是褒还是贬? 联盟内被捧杀的五位球员都有谁呢? 有一个喜欢捧杀你的室友是什么体验? 鲁迅杂文名篇