随机读取使用MapViewOffile的文件
randomly reading a file with mapviewoffile
我有一个非常大的文件,我想使用CreateFileMapping和MapViewOffile来根据给定的标识符号提取10个字节。所以这是我徒劳的尝试,
char* Read(char*pFilename, int id)
{
HANDLE hFile = ::CreateFile(pFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GetSystemInfo(&sysInfo);
DWORD dwSysGran = sysInfo.dwAllocationGranularity;
DWORD dwFileMapStart = ((id*10/ dwSysGran)*dwSysGran);
DWORD dwMapViewSize = (id*10 % dwSysGran) + 10;
DWORD dwFileMapSize = id*10 + 10;
char data[10];
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwFileMapSize, NULL);
if (hMap != NULL)
{
char *rawBuffer = (char*)MapViewOfFile(hMap, FILE_MAP_READ, 0, dwFileMapStart, dwMapViewSize);
memcpy(&data[0], rawBuffer, 10);
UnmapViewOfFile(rawBuffer);
}
//...
return data;
}
例如,如果用户输入一个名为" targeweapondata.ucc"和 an identifier = 122
的文件然后,我的程序需要从文件中的1220 th byte开始读取10个字节的文本,然后将其返回以进行进一步处理。
我仅根据我发现的几个资源来编写此代码,直到现在,我还没有对地球到底有什么彻底的了解
_In_ DWORD dwFileOffsetHigh,
_In_ DWORD dwFileOffsetLow,
在这两个功能中确实是指这样做。而且我想我的参数传递到了这些程序中,就像上面的程序中显示不正确。
-
在此处使用文件映射的理由很少。打开,寻找和阅读。文件映射不会更快地神奇。
-
dwFileOffsetHigh
和dwFileOffsetLow
合并到"视图"开始的文件中的64位偏移。从不同的偏移开始,您可以对单个文件映射的多个视图进行多个视图。偏移必须是页面大小的倍数。因此,您无法在任何想要的地方开始 -
dwFileMapSize
(高和低是64位值)必须是映射中可用的文件的最大大小。 -
磁盘故障和磁盘去除可能会导致(系统)异常。如果您不希望您的程序在这种情况下崩溃,则需要处理。
-
请注意,您的偏移规范允许10字节段越过页面边界。您必须确保您的视图伸展两页
您的计算看起来正确,但是您忘记了rawBuffer
的视图指向偏移dwFileMapStart
而不是id*10
。
我会尝试这样的事情:
char* Read(char*pFilename, int id)
{
HANDLE hFile = ::CreateFile(pFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GetSystemInfo(&sysInfo);
DWORD dwSysGran = sysInfo.dwAllocationGranularity;
DWORD dwSize = 10;
DWORD dwOffset = id*dwSize;
DWORD dwFileMapStart = ((dwOffset/dwSysGran)*dwSysGran);
DWORD dwMapViewSize = dwOffset + dwSize - dwFileMapStart;
char data[10];
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMap != NULL)
{
char *rawBuffer = (char*)MapViewOfFile(hMap, FILE_MAP_READ, 0, dwFileMapStart, dwMapViewSize);
memcpy(&data[0], rawBuffer + (dwOffset - dwFileMapStart), dwSize);
UnmapViewOfFile(rawBuffer);
}
//...
return data;
}
(我尚未测试此代码,所以可能有一些错别字。但是它应该给您基本的想法。)
如果文件可能大于4GB,则需要进行64位计算。
请注意,(取决于文件大小和应用程序的位置),维护整个文件的永久映射视图可能比每次需要读取10个字节时创建新的映射更有意义。至少即使您想每次重新映射视图,也要考虑维护永久映射对象;您会发现它大大减少了开销。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 随机读取使用MapViewOffile的文件
- 文件映射IPC挂起MapViewOfFile调用