分块内存映射处理大文件-例子

参考 :http://user.qzone.qq.com/382164370/infocenter#!app=2&via=QZ.HashRefresh&pos=1363445766

内存映射文件可以用于3个不同的目的

• 系统使用内存映射文件,以便加载和执行. exe和DLL文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。

• 可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I/O操作,并且可以不必对文件内容进行缓存

• 可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互之间共享数据。Windows确实提供了其他一些方法,以便在进程之间进行数据通信,但是这些方法都是使用内存映射文件来实现的,这使得内存映射文件成为单个计算机上的多个进程互相进行通信的最有效的方法。

使用内存映射数据文件 

若要使用内存映射文件,必须执行下列操作步骤:

1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件。

2) 创建一个文件映射内核对象,告诉系统该文件的大小和你打算如何访问该文件。

3) 让系统将文件映射对象的全部或一部分映射到你的进程地址空间中。

当完成对内存映射文件的使用时,必须执行下面这些步骤将它清除:

1) 告诉系统从你的进程的地址空间中撤消文件映射内核对象的映像。

2) 关闭文件映射内核对象。

3) 关闭文件内核对象。


      文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC提供的CFile类等。一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB、几百GB、乃至几TB的海量存储,再以通常的文件处理方法进行处理显然是行不通的。所以可以使用内存文件映射来处理数据,网上也有铺天盖地的文章,但是映射大文件的时候又往往会出错,需要进行文件分块内存映射,这里就是这样的一个例子,教你如何把文件分块映射到内存。


//
// 该函数用于读取从CCD摄像头采集来的RAW视频数据当中的某一帧图像,
// RAW视频前596字节为头部信息,可以从其中读出视频总的帧数,
// 帧格式为1024*576*8
/* 
参数:pszPath:文件名dwFrame: 要读取第几帧,默认读取第2帧
*/
BOOL  MyFreeImage::LoadXRFrames(TCHAR *pszPath, DWORD dwFrame/* = 2*/ )
{// get the frames of X-Ray framesBOOL bLoop = TRUE;int	i;int width = 1024;int height = 576;int bitcount = 8;			//1, 4, 8, 24, 32////Build bitmap headerBITMAPFILEHEADER bitmapFileHeader; BITMAPINFOHEADER bitmapInfoHeader; BYTE			 rgbquad[4];			// RGBQUADint				 index = 0;DWORD widthbytes = ((bitcount*width + 31)/32)*4;		//每行都是4的倍数  DWORD的倍数  这里是 576-TRACE1("widthbytes=%d\n", widthbytes);switch(bitcount) { case 1: index = 2; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2*4); break; case 4: index = 16; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 16*4); break; case 8: index = 256; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)); break; case 24: case 32: index = 0; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)); break; default:break;} //构造Bitmap文件头BITMAPFILEHEADER bitmapFileHeader.bfType = 0x4d42;    // 很重要的标志位  BM 标识bitmapFileHeader.bfSize = (DWORD)(bitmapFileHeader.bfOffBits + height * widthbytes);		//bmp文件长度  bitmapFileHeader.bfReserved1 = 0; bitmapFileHeader.bfReserved2 = 0; //构造Bitmap文件信息头BITMAPINFOHEADER bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapInfoHeader.biWidth = width; bitmapInfoHeader.biHeight = height; bitmapInfoHeader.biPlanes = 1; bitmapInfoHeader.biBitCount = bitcount;bitmapInfoHeader.biCompression = BI_RGB;  // 未压缩bitmapInfoHeader.biSizeImage = height * widthbytes; bitmapInfoHeader.biXPelsPerMeter = 3780; bitmapInfoHeader.biYPelsPerMeter = 3780; bitmapInfoHeader.biClrUsed = 0; bitmapInfoHeader.biClrImportant = 0; //创建BMP内存映像,写入位图头部BYTE *pMyBmp = new BYTE[bitmapFileHeader.bfSize];		// 我的位图pMyBmpBYTE *curr = pMyBmp;									// curr指针指示pMyBmp的位置memset(curr, 0, bitmapFileHeader.bfSize); //写入头信息 memcpy(curr, &bitmapFileHeader,sizeof(BITMAPFILEHEADER));curr = pMyBmp + sizeof(BITMAPFILEHEADER); memcpy(curr, &bitmapInfoHeader,sizeof(BITMAPINFOHEADER)); curr += sizeof(BITMAPINFOHEADER);//构造调色板 , 当像素大于8位时,就没有调色板了。if(bitcount == 8) {rgbquad[3] = 0;										//rgbReservedfor(i = 0; i < index; i++) { rgbquad[0] = rgbquad[1] = rgbquad[2] = i; memcpy(curr, rgbquad, sizeof(RGBQUAD)); curr += sizeof(RGBQUAD); } }else if(bitcount == 1) { rgbquad[3] = 0;										//rgbReservedfor(i = 0; i < index; i++) { rgbquad[0] = rgbquad[1] = rgbquad[2] = (256 - i)%256; memcpy(curr, rgbquad, sizeof(RGBQUAD)); curr += sizeof(RGBQUAD); } } //// 文件映射,从文件中查找图像的数据//Open the real file on the file systemHANDLE hFile = CreateFile(pszPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE){DWORD dwError = GetLastError();ATLTRACE(_T("MapFile, Failed in call to CreateFile, Error:%d\n"), dwError);SetLastError(dwError);bLoop = FALSE;return FALSE;}//Create the file mapping objectHANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);if (hMapping == NULL){DWORD dwError = GetLastError();ATLTRACE(_T("MapFile, Failed in call to CreateFileMapping, Error:%d\n"), dwError);// Close handleif (hFile != INVALID_HANDLE_VALUE){CloseHandle(hFile);hFile = INVALID_HANDLE_VALUE;}SetLastError(dwError);bLoop = FALSE;return FALSE;}// Retrieve allocation  granularitySYSTEM_INFO sinf;GetSystemInfo(&sinf);DWORD dwAllocationGranularity = sinf.dwAllocationGranularity;// Retrieve file size// Retrieve file sizeDWORD dwFileSizeHigh;__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);qwFileSize |= (((__int64)dwFileSizeHigh) << 32);CloseHandle(hFile);// Read Image__int64 qwFileOffset = 0;									// 偏移地址DWORD   dwBytesInBlock = 0,									// 映射的块大小dwStandardBlock = 100* dwAllocationGranularity ;	// 标准块大小DWORD   dwFrameSize = height*width;					        // 计算一帧图像的数据量,不包括头部信息DWORD   dwCurrentFrame = 1;dwBytesInBlock = dwStandardBlock;if (qwFileSize < dwStandardBlock)dwBytesInBlock  = (DWORD)qwFileSize;//Map the view  LPVOID lpData = MapViewOfFile(hMapping,  FILE_MAP_ALL_ACCESS, static_cast<DWORD>((qwFileOffset & 0xFFFFFFFF00000000) >> 32), static_cast<DWORD>(qwFileOffset & 0xFFFFFFFF), dwBytesInBlock);if (lpData == NULL){DWORD dwError = GetLastError();ATLTRACE(_T("MapFile, Failed in call to MapViewOfFile, Error:%d\n"), dwError);// Close Handleif (hMapping != NULL){CloseHandle(hMapping);hMapping = NULL;}SetLastError(dwError);bLoop = FALSE;return FALSE;}BYTE  *lpBits = (BYTE *)lpData;BYTE  *curr1, *curr2, *lpEnd;curr1 = lpBits;							// seek to startcurr2 = lpBits + 596;					// seek to first framelpEnd = lpBits + dwBytesInBlock;		// seek to end// Read video infomationKMemDataStream streamData( curr1, dwBytesInBlock);ReadXRHeader(streamData);while(bLoop){DWORD dwTmp = lpEnd - curr2;		//内存缓冲剩余的字节if ( dwTmp >= dwFrameSize )	{if(dwCurrentFrame == dwFrame){memcpy(curr, curr2, dwFrameSize);bLoop = FALSE;}curr2 += dwFrameSize;}else		//内存中不够一帧数据{DWORD dwTmp2 = dwFrameSize - dwTmp;			// 一副完整的帧还需要dwTmp2字节if (dwCurrentFrame == dwFrame){memcpy(curr, curr2, dwTmp);curr += dwTmp;}
                        
			//1、首先计算文件的偏移位置
                        qwFileOffset += dwBytesInBlock;
//2、 检查还可以映射多少字节的东东到内存里面if ( qwFileSize - qwFileOffset < dwStandardBlock)dwBytesInBlock = (DWORD)(qwFileSize - qwFileOffset);//3、重新映射文件UnmapViewOfFile(lpData);lpData = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, static_cast<DWORD>((qwFileOffset & 0xFFFFFFFF00000000) >> 32), static_cast<DWORD>(qwFileOffset & 0xFFFFFFFF), dwBytesInBlock);if (lpData == NULL) // 一定要检查,不然可能内存映射失败{DWORD dwError = GetLastError();ATLTRACE(_T("MapFile, Failed in call to MapViewOfFile, Error:%d\n"), dwError);SetLastError(dwError);bLoop = FALSE;break;}curr2 = lpBits = (BYTE *)lpData;lpEnd = lpBits + dwBytesInBlock; // seek to endif (dwCurrentFrame == dwFrame){memcpy(curr, curr2, dwTmp2);bLoop = FALSE;}curr2 += dwTmp2;}dwCurrentFrame++;if (dwCurrentFrame > ((LPKINFO)m_VideoInfoHeader)->frames ) // 到达文件末尾{bLoop = FALSE;}}//将内存流 pMyBmp 转为bitmapKMemDataStream stream(pMyBmp, bitmapFileHeader.bfSize, true);if(!LoadFromMemory(FIF_BMP, stream))return FALSE;//if (lpData != NULL){//FlushViewOfFile(lpData, 0);UnmapViewOfFile(lpData);lpData = NULL;}//remove the file mappingif (hMapping != NULL){CloseHandle(hMapping);hMapping = NULL;}return TRUE;}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频图像处理仿真测试系统

视频图像处理仿真测试系统 1、仿真测试系统框架 一个完善的仿真测试系统对于图像处理算法的设计至关重要。这个测试系统至少要完成以下功能: (1)模拟可配置的视频流(单帧的视频即为一幅图像)。 (2)模拟视频捕获,生成视频数据。 (3)测试系统与testbench及视频流的数据…

cetk使用方法--nand flash测试

测试环境&#xff1a; OS&#xff1a; wince5.0 cpu&#xff1a; J9 image&#xff1a; ramimage(开始是一个binfs分区存放ramimage&#xff0c;后面是一个fat分区存放user data&#xff0c;它们公用一个块驱动) note&#xff1a; 具体测试command的书写要参照注册表的配置…

如是•吴震寰个展

如是 • 吴震寰个展。我把他的创作称为&#xff02;元艺术&#xff0f;元创作&#xff02;。他用看似简单幼稚平凡的笔墨和行为&#xff0c;将前人积累的艺术经验&#xff0c;当然也包括他自己的经验全部抹杀和归零。让绘画和艺术回到原始的岩画时代&#xff0c;回到自己幼时产…

VGA显示器驱动设计与验证

VGA显示器驱动设计与验证 1、VGA显示原理 VGA显示器显示图像,并不是直接让图像在显示器上显示出来,而是采用扫描的方式,将构成图像的像素点,在行同步信号和场同步信号的同步下,按照从上到下、由左到到右的顺序扫描到显示屏上。 VGA显示器的扫描规律 (1)在行、场同步信…

张洁的新书「流浪的老狗」

张洁的最新书「流浪的老狗」终于出版。这是她第一部文学和摄影的游记&#xff0c;纪录了她一个人背着行囊游历世界的感悟。她驻足的地方大多是不为外人所知的小角落&#xff0c;她深入到世界最有特色和活力的肌理当中&#xff0c;记下她的独特感受和这个世界让我们忽略的以及我…

KITL--概念篇

KITL(Kernel Independent Transport Layer)是基于Windows CE平台的一种软件技术&#xff0c;开发商基于它可以很容易地支持各种调试功能。因为Windows CE的调试是一种远程调试&#xff0c;所以开发工作站&#xff08;运行PB的机器&#xff09;和设备端必须要有相应的通信通道&a…

2006年统计的国内外的一些机器视觉公司汇总

转摘自网上上海&#xff1a;上海恒意得信息科技有限公司法视特&#xff08;上海&#xff09;公司上海锡明科技上海东冠科技上海真锐科技上海元中光学仪器海澳光学仪器日本CCS代表处日本欧姆龙代表处日本松下代表处美国DVT代表处美国COGNEX代表处美国邦纳工程有限公司I2S&#x…

平遥摄影展:卡农•布斯克茨和他的「一天的结束」

平遥国际摄影展&#xff0c;一年一度&#xff0c;端相机人的节日。满街是镜头和摄影背心的攒动。我朋友说&#xff1a;没看到好照片&#xff0c;倒是看到不少好相机。这或许就是中国摄影界的写照&#xff0c;也是平遥摄影展的困境。如果没遇到布斯科茨&#xff0c;或许我真的白…

SystemVerilog声明的位置

SystemVerilog声明的位置 1、包&#xff08;package&#xff09; (1)包的定义 SystemVerilog的包在package和endpackage之间定义 包中可以包含的可综合的结构有 &#xff08;1&#xff09;parameter和localparam常量定义 &#xff08;2&#xff09;const变量定义 &#xff08;…

[学习] FPGA之ip核

>> ip核之概念和分类IP&#xff08;Intellectual Property&#xff09;内核模块是一种预先设计好的甚至已经过验证的具有某种确定功能的集成电路、器件或部件。它有几种不同形式。IP内核模块有行为&#xff08;behavior&#xff09;、结构&#xff08;structure&#xff…

常见的机器视觉软件

一、开源的OpenCV 机器视觉我们最常用的软件是OpenCV&#xff08;Intel OpenSource Computer Vision Library&#xff09;&#xff0c;它的中文论坛http://www.opencv.org.cn/index.php里面有非常清楚的介绍。 二、VisionPro7.0系统&#xff0c;快速开发强大的应用系统 康耐视…

$unit编译单元声明

$unit编译单元声明 SystemVerilog含有编译单元。 相比Verilog&#xff0c;SystemVerilog增加了编译单元的概念。编译单元是同时编译的所有源文件。编译单元为软件工具提供了一种对整个设计子块单独编译的方法。一个子块可能包含第一个或多个模块&#xff08;module&#xff09…

[学习] FPGA之基本原理(可能理解不对)

>> 什么是fpga FPGA是英文Field Programmable Gate Array的缩写&#xff0c;即现场可编程门阵列&#xff0c;它是在PAL、GAL、EPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中 的一种半定制电路而出现的&#xff0c;既解决了定制电路的不足…

忧云:喻红艺术展观后

长征空间。喻红的个展《忧云 wondering clouds》&#xff0c;中文标题似过诗意&#xff0c;而英文可能更准确表达其意图。这幅连体大画至少有15米长&#xff0c;非常壮观&#xff0c;色彩变化&#xff0c;人物的形态&#xff0c;复杂而有序。既有写实也有表现&#xff0c;既有真…

阶乘和

#include <stdio.h>// __int64的范围是 [0, 2^64),即0~18446744073709551615(约1800亿亿) static unsigned __int64 sum_fac(int n);int main(void) {printf("test sum_fac function.\n\n");for(unsigned int k0; k<20; k){printf("k%dth e sum is: %l…

未命名语句块中的声明

未命名语句块中的声明 命名块中的局部变量 Verilog允许在命名的begin…end或fork…join块中声明局部变量。局部变量声明的通常用法是声明一个临时变量进行循环控制。局部变量避免了对同名但用途不同的模块模块级变量的无意访问。下面的代码段声明了两个都叫i的变量&#xff0c…

故乡的路:十位少数民族摄影师联展

故乡的路&#xff1a;10位少数民族摄影师联展。映艺术中心。参展的有蒙古族、维吾尔族、回族、纳西族、傣族、白族、彝族、拉祜族、藏族等。民族是一个视点&#xff0c;故乡也是一个视点&#xff0c;两者的交叉&#xff0c;透过现代化的相机和镜头&#xff0c;获得了一种独特的…

kitl协议包简述

英文版参照网址http://blogs.msdn.com/ce_base/archive/2006/06/27/648747.aspx 下面是翻译过来的&#xff0c;可能有错哦&#xff0c;呵呵 KITL概述 KITL——Kernel Independent Transport Layer&#xff0c;CE驱动调试的基本调试协议。KITL提供 1、 传输初始化 2、 数…

敏捷转型中的看板

Scrumban最初是一种从Scrum向精益看板转换的机制&#xff0c;现在它已经支持双方向的转换&#xff0c;并可以应用到项目和精简BAU(常规商业运营)工作流。能够实施Scrum和精益方法的相互转换自然是很好的。但当你的客户不具备实践这些方法的条件时&#xff0c;你如何去帮助他们实…

GDIPlus灰度化图像

将RGB彩色图像转为8位的索引颜色 先定义一个宏 // Greyscale conversion #define GREY(r, g, b) (BYTE)(((WORD)r * 77 (WORD)g * 150 (WORD)b * 29) >> 8 //#define GREY(r, g, b) (BYTE)(((WORD)r * 169 (WORD)g * 256 (WORD)b * 87) >> 9)// Grayscale, 将…