当前位置:首页 > 内存 > 正文

内存映射处理大文件

  • 内存
  • 2024-06-07 10:44:58
  • 1493

一、我c++要处理大量数据,一个都是几百m,如何存入内存.内存映射应该可以工作。内存映射使用文件作为内存区域。
类别:内存映射文件
主题:使用文件的内存映射文件
演示:
1:创建或者打开文件内核对象:
//Openthefileforreadingandwriting。
HANDLEhFile=CreateFile(pszPathname,GENERIC_WRITE|GENERIC_READ,0,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//由于hFile为INVALID_HANDLE_VALUE,所以下面的CreateFileMapping仍然可以正常运行,
//所以这里必须检查hFile!
if(hFile==INVALID_HANDLE_VALUE){
chMB("Filecouldnotbeopened.");
return(FALSE);
}
2:创建文件映射核心对象:
//Getthesizeofthefile(Iassumethewholefilecanbemapped).
DWORDdwFileSize=GetFileSize(hFile,NULL);
//e-mappingobjectis1characterize
//biggerthanatathefileozerendstring(file).因为我不知道不知道
//文件是否包含ANSI或Unicode字符,我假设最坏情况
//并添加thesizeofaWCHAR而不是CHAR。
HANDLEhFileMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,
PAGE_READWRITE,
sizeof(WCHAR),//如果文件小于指定大小,该函数会扩大文件的大小,
//使磁盘上的文件变大。这样,当文件用作内存时-映射文件将来会在物理内存中存在。
NULLf//这个文件映射对象的名称用于与其他进程共享对象,这里我们不再需要了。
);
if(hFileMap==NULL){
chMB("Filemap无法打开。");
CloseHandle(hFile);
return(FALSE);
}
3:将文件数据映射到进程地址空间:
创建文件映射对象后,系统仍然需要为文件数据存储文件。地址空间区域,
并提交文件数据作为映射到该区域的物理内存。
==NULL){
chMB("Couldnotmapviewoffile.");
CloseHandle(hFileMap);
CloseHandle(hFile);
return(FALSE);
}
4:现在我们已经通过pvFile获得了图像显示的起始地址,我们可以对显示进行一些操作了:
ANSI版本:
PSTRpchANSI=(PSTR)pvFile;
UNICODE版本:
PWSTRpchUnicode=(PWSTR)pvFile;
5:从进程地址空间中删除文件数据映像:
//Cleanupeverythingbeforexiting.
UnmapViewOfFile(pvFile);
6:关闭文件映射对象和文件对象:
CloseHandle(hFileMap);
CloseHandle(hFile);
定义:
HANDLECreateFileMapping(
HANDLEhFile,//handletofile
LPSECURITY_ATTRIBUTESlpAttributes,//安全
DWORDflProtect,//保护
DWORDdwMaximumSizeHigh,//高阶DWORDofsize
DWORDdwMaximumSizeLow,//低阶DWORDofsize
LPCTSTRlpName//对象名称
IDleMapViewOFFFiFi);
LPfVOFi(
HANDLehFileMappingObject,//句柄到文件映射对象
DWORDdwDesiredAccess,//访问模式
DWORDdwFileOffsetHigh,//高阶DWORDofoffset
DWORDdwFileOfflowsetLowset,//BytesToMap//numberofbytestomap
);
BOOLUnmapViewOfFile(
LPCVOIDlpBaseAddress//startingaddress
);
提示:
您也可以尽早关闭该对象,以消除可能的资源泄漏属性,例如如:
HANDLEhFile=CreateFile(...);
HANDLehFileMapping=CreateFileMapping(hFile,...);
CloseHandle(hFile);
PVOIDpvFile=MapViewOfFile(hFileMapping,...);
CloseHandle(hFileMapping);
//使用内存映射文件。
UnmapViewOfFile(pvFile);


二、c#如何读取20g以上的大文件

在C#中读取超过20GB的大文件时,建议使用流,以避免整个文件一次性加载到内存中导致内存不足的问题。

以下是使用大文件流的代码示例:

using(FileStreamfs=newFileStream(@"C:\path\to\large\"、、)

{

使用(BufferedStreambs=newBufferedStream(fs)

{

使用(StreamReadersr=newStreamReader(bs)

{

stringline;

while((line=ne())!=nonep

{

//处理数据行的逻辑

}

}

}

}

在这段代码中我们使用了三个流对象:

FileStream:打开一个大文件并使用输入流

BufferedStream:用于加快数据读取速度并减少数量使用硬内存读取器

StreamReader:逐行读取文本数据

在堆栈中,我们可以处理每一行数据的逻辑。因为只有一行数据读取数据时,使用的内存较小,可以避免每个文件过大造成的冗余问题。这可以通过将StreamReader对象的ReadLine方法替换为ReadLineAsync的异步版本来完成。