gpt4 book ai didi

c++ - 是否可以缓存从 MapViewOfFile 返回的映射区域?

转载 作者:太空宇宙 更新时间:2023-11-04 11:39:03 25 4
gpt4 key购买 nike

下午好,众所周知,在处理大文件时无法映射到 Win32 中的一个 View ,创建仔细映射的代码并根据需要取消映射文件区域。 pastebin 网址是:

我创建并测试了一个处理大文件的 cMemoryMappedFile 类不能映射到 Win32 中的一个 View 。我测试了类(class)并发现虽然它功能正常,但需要很长时间(即 3 秒)随机访问。这是因为该类必须取消映射和映射文件每个随机访问的区域。我想知道是否有可能缓存从 MapViewFile 返回的映射区域以加速随机访问。

昨天,我注意到 UnMapViewOfFile 使之前的从 MapViewOfFile 返回的映射区域。有没有人有想法如何通过缓存或其他方式加速随机访问?

当前视口(viewport)为 128KB。我相信如果我放大viewport 它将减少对 UnMapViewOfFile 的调用次数和 MapViewOfFile。但是,我想知道是否可以使用其他方法。请看方法,
char* cMemoryMappedFile::GetPointer(int , bool) 看看如何视口(viewport)随文件映射移动。谢谢。

类的 pastebin url 是
> 。我在这里添加源代码以防万一没有人可以访问该 url。

// cMemoryMappedFile.Cpp
#include "cException.h"
#include "cMemoryMappedFile.h"

#define BUFFER_SIZE 10

#define MEM_BLOCK_SIZE 65536 * 2

/**
\class cMemoryMappedFile
\brief Encapsulation of the Windows Memory Management API.

The cMemoryMapped class makes some memory mapping operations easier.
*/

/**
\brief Constructor for cMemoryMappedFile object.

\param FileSize Size of file.
\param OpenMode File open mode
\param AccessModes File access mode
\param ShareMode File sharing mode
\param Flags File attributes and flags
\param ShareMode File sharing mode
\param Flags File attributes and flags
\param Security Security Attributes
\param Template Extended attributes tp apply to a newly created file
*/
cMemoryMappedFile::cMemoryMappedFile(long FileSize_, OpenModes OpenMode_,AccessModes AccessMode_,
ShareModes ShareMode_,long Flags_,void *Security_,FILEHANDLE Template_) {
FileSize = FileSize_;
char buffer[BUFFER_SIZE];
DWORD dwRetVal = 0;
UINT uRetVal = 0;
DWORD dwPtr = 0;
BOOL isSetEndOfFile = FALSE;
LARGE_INTEGER Distance_;
DWORD ErrorCode = 0;

char lpTempPathBuffer[MAX_PATH];

PreviousNCopy = 0;
PreviousN = 0;

// Gets the temp path env string (no guarantee it's a valid path).
dwRetVal = GetTempPath(MAX_PATH, // length of the buffer
lpTempPathBuffer); // buffer for path
if (dwRetVal > MAX_PATH || (dwRetVal == 0))
{
throw cException(ERR_MEMORYMAPPING,"");
}

// Generates a temporary file name.
uRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files
TEXT("DEMO"), // temp file name prefix
0, // create unique name
TempFileName); // buffer for name
if (uRetVal == 0)
{

throw cException(ERR_MEMORYMAPPING,lpTempPathBuffer);
}
// Creates the new file
hFile = CreateFile((LPTSTR) TempFileName, // file name
AccessMode_, // open for write
0, // do not share
(SECURITY_ATTRIBUTES *) Security_, // default security
OpenMode_, // CREATE_ALWAYS,
Flags_,// normal file
Template_); // no template
if (hFile == INVALID_HANDLE_VALUE)
{
throw cException(ERR_MEMORYMAPPING,TempFileName);
}
Distance_.LowPart = (ULONG)FileSize_;
Distance_.HighPart = 0; // (ULONG)(FileSize_ >> 32);
dwPtr = ::SetFilePointer(hFile,Distance_.LowPart,
&(Distance_.HighPart), FileBegin);

if (dwPtr == INVALID_SET_FILE_POINTER){
throw cException(ERR_MEMORYMAPPING,TempFileName);
}
isSetEndOfFile = SetEndOfFile(hFile);
if (!isSetEndOfFile){
ErrorCode = GetLastError();
throw cException(ERR_MEMORYMAPPING,TempFileName);
}
hMapping=::CreateFileMapping(hFile,(SECURITY_ATTRIBUTES *)Security_,PAGE_READWRITE,0,0,0);
if (hMapping==NULL)
throw cException(ERR_MEMORYMAPPING,TempFileName);

MapPtr = 0;
adjustedptr = 0;
prevadjustedptr = adjustedptr;

FilePath=new char[strlen(TempFileName)+1];
strcpy(FilePath,TempFileName);
}



char * cMemoryMappedFile::GetPointer(int n, bool Caching){
unsigned int baseoff;
if( n < MEM_BLOCK_SIZE / 2)
{
baseoff = 0;
}
else
{
baseoff = ((n + MEM_BLOCK_SIZE / 4) &
(~(MEM_BLOCK_SIZE / 2 - 1))) - MEM_BLOCK_SIZE / 2;

}
// the correct memory mapped view is already mapped in
if (adjustedptr != 0 && mappedoffset == baseoff && Caching)
return adjustedptr;
else if (Caching)
{
/*
retrieve adjustedptr from cache
*/
}
// get a new memory mapped viewport
else{
if (MapPtr){
UnmapViewOfFile(MapPtr);
PreviousNCopy = PreviousN;
prevadjustedptr = adjustedptr;
}
PreviousN = n;
mappedlength = min(FileSize - baseoff, MEM_BLOCK_SIZE);

// MapViewOfFile should be aligned to 64K boundary

MapPtr = (char*)::MapViewOfFile( hMapping,
FILE_MAP_WRITE | FILE_MAP_READ, 0,
baseoff, mappedlength);
mappedoffset = baseoff;
adjustedptr = MapPtr - mappedoffset;
printf("Value: %u n: %u\n",adjustedptr[n],n);

/*
cache PreviousNCopy,PreviousN, prevadjustedptr[PreviousNCopy]
*/

}
return adjustedptr;
}

最佳答案

你可以有一个“自由列表”风格的缓存——当你的类(class)的用户要求取消映射一个你并不真正关心的区域时,你只需将它添加到列表中即可。当他们要求映射一个新区域时,如果可能的话,你可以重用现有的映射,否则你创建一个新的映射,如果你打开了太多的映射,或者映射的大小在哪里,就从缓存中删除最近最少使用的映射缓存的映射太大。

关于c++ - 是否可以缓存从 MapViewOfFile 返回的映射区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5173931/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com