用Win32API实现内存映射磁盘将文件夹映射为磁盘后怎么去读

sponsored links
分块内存映射处理大文件例子
参考 :http://user.qzone.qq.com//infocenter#!app=2&via=QZ.HashRefresh&pos=
内存映射文件可以用于3个不同的目的
o 系统使用内存映射文件,以便加载和执行. exe和DLL文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。
o 可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I/O操作,并且可以不必对文件内容进行缓存。
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字节为头部信息,可以从其中读出视频总的帧数,
// 帧格式为
pszPath:文件名
dwFrame: 要读取第几帧,默认读取第2帧
MyFreeImage::LoadXRFrames(TCHAR *pszPath, DWORD dwFrame/* = 2*/ )
// get the frames of X-Ray frames
BOOL bLoop = TRUE;
int width = 1024;
int height = 576;
int bitcount = 8;
//1, 4, 8, 24, 32
//////////////////////////////////////////////////////////////////////////
//Build bitmap header
BITMAPFILEHEADER bitmapFileH
BITMAPINFOHEADER bitmapInfoH
rgbquad[4];
// RGBQUAD
index = 0;
DWORD widthbytes = ((bitcount*width + 31)/32)*4;
//每行都是4的倍数
DWORD的倍数
这里是 576-
TRACE1(&widthbytes=%d\n&, widthbytes);
switch(bitcount) {
index = 2;
bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2*4);
index = 16;
bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 16*4);
index = 256;
bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD));
index = 0;
bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
//构造Bitmap文件头BITMAPFILEHEADER
bitmapFileHeader.bfType = 0x4d42;
// 很重要的标志位
bitmapFileHeader.bfSize = (DWORD)(bitmapFileHeader.bfOffBits + height * widthbytes);
//bmp文件长度
bitmapFileHeader.bfReserved1 = 0;
bitmapFileHeader.bfReserved2 = 0;
//构造Bitmap文件信息头BITMAPINFOHEADER
bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfoHeader.biWidth =
bitmapInfoHeader.biHeight =
bitmapInfoHeader.biPlanes = 1;
bitmapInfoHeader.biBitCount =
bitmapInfoHeader.biCompression = BI_RGB;
bitmapInfoHeader.biSizeImage = height *
bitmapInfoHeader.biXPelsPerMeter = 3780;
bitmapInfoHeader.biYPelsPerMeter = 3780;
bitmapInfoHeader.biClrUsed = 0;
bitmapInfoHeader.biClrImportant = 0;
//创建BMP内存映像,写入位图头部
BYTE *pMyBmp = new BYTE[bitmapFileHeader.bfSize];
// 我的位图pMyBmp
BYTE *curr = pMyB
// 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;
//rgbReserved
for(i = 0; i & i++)
rgbquad[0] = rgbquad[1] = rgbquad[2] =
memcpy(curr, rgbquad, sizeof(RGBQUAD));
curr += sizeof(RGBQUAD);
}else if(bitcount == 1)
rgbquad[3] = 0;
//rgbReserved
for(i = 0; i & 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 system
HANDLE 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 object
HANDLE 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 handle
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
SetLastError(dwError);
bLoop = FALSE;
return FALSE;
// Retrieve allocation
granularity
SYSTEM_INFO
GetSystemInfo(&sinf);
DWORD dwAllocationGranularity = sinf.dwAllocationG
// Retrieve file size
// Retrieve file size
DWORD dwFileSizeH
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) && 32);
CloseHandle(hFile);
// Read Image
__int64 qwFileOffset = 0;
// 偏移地址
dwBytesInBlock = 0,
// 映射的块大小
dwStandardBlock = 100* dwAllocationG // 标准块大小
dwFrameSize = height*
// 计算一帧图像的数据量,不包括头部信息
dwCurrentFrame = 1;
dwBytesInBlock = dwStandardB
if (qwFileSize & dwStandardBlock)
dwBytesInBlock
= (DWORD)qwFileS
//Map the view
LPVOID lpData = MapViewOfFile(hMapping,
FILE_MAP_ALL_ACCESS,
static_cast&DWORD&((qwFileOffset & 0xFFFFFFFF) && 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 Handle
if (hMapping != NULL)
CloseHandle(hMapping);
hMapping = NULL;
SetLastError(dwError);
bLoop = FALSE;
return FALSE;
*lpBits = (BYTE *)lpD
*curr1, *curr2, *lpE
curr1 = lpB
// seek to start
curr2 = lpBits + 596;
// seek to first frame
lpEnd = lpBits + dwBytesInB
// seek to end
// Read video infomation
KMemDataStream streamData( curr1, dwBytesInBlock);
ReadXRHeader(streamData);
while(bLoop)
DWORD dwTmp = lpEnd - curr2;
//内存缓冲剩余的字节
if ( dwTmp &= dwFrameSize )
if(dwCurrentFrame == dwFrame)
memcpy(curr, curr2, dwFrameSize);
bLoop = FALSE;
curr2 += dwFrameS
//内存中不够一帧数据
DWORD dwTmp2 = dwFrameSize - dwT
// 一副完整的帧还需要dwTmp2字节
if (dwCurrentFrame == dwFrame)
memcpy(curr, curr2, dwTmp);
curr += dwT
//1、首先计算文件的偏移位置
qwFileOffset += dwBytesInB//2、 检查还可以映射多少字节的东东到内存里面if ( qwFileSize - qwFileOffset & dwStandardBlock)dwBytesInBlock = (DWORD)(qwFileSize - qwFileOffset);//3、重新映射文件UnmapViewOfFile(lpData);lpData = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS,
static_cast&DWORD&((qwFileOffset & 0xFFFFFFFF) && 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;}curr2 = lpBits = (BYTE *)lpDlpEnd = lpBits + dwBytesInB // 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;}
内存映射修改大文件 四川师范大学 tacher 下载源代码 本文介绍利用内存映射文件修改大文件:在大文件内存前加入一段数据,若要使用内存映射文件,必须执行下列操作步骤: 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件: 创建一个文件映射内核对象,告诉系统该文件的大小和你打算如何访问该文件: 让系统将文件映射对象的全部或一部分映 ...
内存映射对于大文件的使用 http://blog.csdn.net/bdmh/article/details/6369250 平时很少使用大文件的内存映射,碰巧遇到了这样的要求,所以把过程记录下来,当给各位一个引子吧,因为应用不算复杂,可能有考虑不到的地方,欢迎交流. 对于一些小文件,用普通的文件流就可以很好的解决,可是对于超大文件,比如2G或者更多,文件流 ...
在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,本文主要讲述Java中用内存映射处理大文件,更多Java专业知识,广州疯狂java培训为你讲解; 在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频 ...
平时很少使用大文件的内存映射,碰巧遇到了这样的要求,所以把过程记录下来,当给各位一个引子吧,因为应用不算复杂,可能有考虑不到的地方,欢迎交流. 对于一些小文件,用普通的文件流就可以很好的解决,可是对于超大文件,比如2G或者更多,文件流就不行了,所以要使用API的内存映射的相关方法,即使是内存映射,也不能一次映射全部文件的大小,所以必须采取分块映射,每次处理一 ...
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验. import java.io.BufferedInputS import java.io.FileI ...内存映射文件及其在广义舒适度仿真中的应用
0引言列车在高速服役过程中,会有很多因素影响到乘客的乘坐舒适性,其中振动、压力、噪声、温度、湿度、照度、运动场景以及车内色彩与布置等物理量对乘客舒适性影响较大。广义舒适度仿真即是运用计算机仿真技术研究振动、压力、噪声、温度、湿度、照度、运动场景以及车内色彩与布置等物理量对乘客的乘坐舒适性的影响。为了准确的模拟服役列车各个物理量参数,通常以毫秒为单位对物理量参数进行计算采样,并将计算数据以文件的形式进行保存,因此保存的数据通常都是几百GB甚至TB的海量数据。文件操作是应用程序最为基本的功能之一,微软的Win32API(Win32Application ProgrammingInterface,应用程序编程接口)和MFC(MicrosoftFoundation Classes,微软基础类库)均提供了很多函数和类支持文件处理,比如WriteFile()、CreateFile()、ReadFile()以及CFile和C++的输入输出流等...&
(本文共4页)
权威出处:
随着计算机技术的飞速发展 ,计算机要处理的数据越来越多 ,数据文件也越来越大 ,要想对大数据量文件进行快速存取 ,用传统的通过I/O文件读取技术将很难满足要求。文件输入和输出 (I/O)是计算机编程中的一个巨大瓶颈。在简单的情况下 ,这是一个耗时较多的阻塞式调用 ,而在复杂情况下 ,就必须产生独立的线程来操作I/O。有时 ,一个独立的线程会引入许多问题 ,如同步、等待等。文件I/O也经常用于进程间通信 (IPC)。除了性能考虑之外 ,IPC有时需要双向的I/O通道 ,但使用简单的文件I/O ,这是很难建立和维持的。同时 ,如果通信不是面向数据流的或有超过两个以上的用户共享时 ,IPC会变得异常复杂。大多数文件I/O的缓冲特性意味着发送进程需要不断的强制系统保存缓冲。解决上述问题较好的方法是使用内存映射文件 (Memory MappedFiles,MMFs) ,让Win32来管理文件I/O、缓冲器和高速缓冲器。本文通过实验 ,对比...&
(本文共2页)
权威出处:
Windows操作系统提供了多种机制,使得多个进程间可以共享数据与相互通信。这些机制包括RPC、C()M、OLE、DDE、窗口消息(WMseC()PYDATA等)、套接字、邮槽、管道、内存映射文件技术等。除套接字、邮槽、管道技术建立在Windows网络技术基础上外,内存映射文件构成了其他共享数据机制的基础。确切地讲,多进程间通信与共享数据的机制均基于内存映射文件,只是在外部添加了不同的外壳以适应不同的应用环境。目前,内存映射文件是Windows环境下最基本,同时也是使用最广泛的数据共享与通信技术,尤其适用于用来管理大型数据流(通常来自文件)以及在单个计算机上运行的多个进程之间共享数据。 另一方面,Windowsgx/Z000/NT平台下输人法的一个特点就是多个应用程序间不再共享一个输人法实例,而是每个应用程序都拥有自己的一个独立的输人法实例,所以必须实现在同一个输人法的多个实例间共享数据,以降低系统的资源耗费。鉴于现代输人法的高...&
(本文共3页)
权威出处:
内存映射文件是win32 API中功能最强大,用途最广泛的功能之一。想一想我们通常是如何操作硬盘中的文件的,不外乎是使用fopen,fseek,fread,fclose等等一些底层通用的文件操作函数一步一步地读取文件中的数据,或者是使用针对某种文件格式的高层文件操作函数,然后在应用程序中对这些数据进行处理。由于从硬盘读、存数据的时间比较长(编者注:这里的时间比较长是相对于CPU的运行速度来说的),应用程序为了能正常运行要不断地与硬盘交换数据,这是多么浪费时间啊!尤其是在操作一个几十M甚至几个G的大型数据文件时,这种方法对程序员来说简直是无法忍受的。那么,怎么办呢?用内存映射文件,它使得应用程序可以像操作内存一样操作外存文件,灵活地使用指针来读取数据。 在具体使用内存映射文件之前,有必要了解一下它的工作原理,这样将更加有利于我们下一步的编程。众所周知,操作系统为了解决系统内存空间不足的状况,采用了分级存储体系,运用段页式的管理方法...&
(本文共2页)
权威出处:
1引言随着数据采集技术和大容量Flash存储器的快速发展,数据采集速度和采集信号路数迅速增加,使得数据容量、数据帧复杂程度也大量增加,这就对采编数据的快速处理和显示提出了越来越高的要求。通常,这类数据都是用普通的文件处理函数和类进行处理,常用的如Win32API的CreateFile()、Write-File()、ReadFile()和MFC提供的CFile类等。这些函数处理灵活,可以满足大多数场合的要求,但是对于某些特殊应用领域,所需要访问的数据达到几个GB甚至更多。这时,如果再用通常的文件处理方法进行处理显然是行不通的。目前,对于上述这种大文件的操作一般是以内存映射文件的方式来加以处理的,文中将针对这种Windows核心编程技术展开讨论[1]。2实现方法内存映射文件允许在Win32进程的虚拟地址空间中保留一段内存区域,并将物理存储器中目标文件提交给该区域,映射到这段虚拟内存之中。这样,物理存储器来自一个已经位于磁盘上的文件,...&
(本文共3页)
权威出处:
引言在Windows系统中,任何一个进程都被赋予其独立的虚拟地址空间,对于一个32位进程,地址空间覆盖的大小为4GB,一个指针可以使用这个4GB空间范围内的任何值,这只是逻辑上的虚拟的地址空间,进程实际只拥有远小于4GB的物理地址空间。进程的虚拟地址空间为每个进程所私有,由windows分配,是实际的物理内存地址的映像,在进程内运行的线程只能访问所处进程的内存空间,所以,不同的进程可以使用相同地址的指针,用来指向属于各自调用进程的内容,而不会由此引起混乱,各进程以虚地址访问存储器,系统再将虚地址转换为物理地址,这一过程并不被进程所感知,对进程是透明的。这种方式有效地分担了程序员负担,使其可以在一个足够大的空间内自由动作,不必考虑会与其它进程发生访问冲突,但也增加了程序员理解上的困难。虚拟地址与物理内存关系如图1:Windows操作系统对内存的管理方式有3种:虚拟内存方式、内存映像文件方式、堆方式。其中虚拟内存的管理方式[1]常用...&
(本文共6页)
权威出处:
扩展阅读:
CNKI手机学问
有学问,才够权威!
xuewen.cnki.net
出版:《中国学术期刊(光盘版)》电子杂志社有限公司
地址:北京清华大学 84-48信箱 大众知识服务
京ICP证040431号&
服务咨询:400-810--9993
订购咨询:400-819-9993
传真:010-他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)python 在python中使用windows内存映射文件 - 为程序员服务
为程序员服务
在python中使用windows内存映射文件
在python中使用windows内存映射文件
采用windows事件和共享内存实现进程间通信。
import win32event as w32e
import win32api as wapi
import mmapfile as mmf
hEvent = w32e.CreateEvent(None , 0 , 0 , &Global\\JmdebuggerEvent&)
#system_info=wapi.GetSystemInfo()
#page_size=system_info[1]
pyMm = mmf.mmapfile(None , &JmdebuggerMem& ,1024 )
if hEvent != None and pyMm != None :
w32e.WaitForSingleObject(hEvent , -1)
buf = pyMm.read(16)
wapi.CloseHandle(hEvent)
pyMm.close()
[python] view plaincopy
import win32event as w32e
import mmapfile as mmf
hEvent = w32e.OpenEvent(w32e.EVENT_ALL_ACCESS , 0 ,&Global\\JmdebuggerEvent&)
pyMm = mmf.mmapfile(None , &JmdebuggerMem& ,1024)
if hEvent != None and pyMm != None:
w32e.SetEvent(hEvent)
pyMm.write(&hello world!&);
您可能的代码
相关聚客文章
荣誉:1548
相关专栏文章他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 c 文件映射磁盘 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信