内存映射读取大容量二进制文件
------
请问大家,用内存映射如何读取一个12G大小的二进制文件,我想从文件的第100亿个字节处读取10000个字节,请问大家该如何实现?
------
无需内存映射,用ReadFile加上偏移就行
------
我的读取方式如下:
//获得文件句柄
HANDLE hFile=CreateFile(
"data.dat", //文件名
GENERIC_READ, //对文件进行读操作
FILE_SHARE_READ,
NULL,
OPEN_EXISTING, //打开已存在文件
FILE_ATTRIBUTE_NORMAL,
0);
DWORD size_low,size_high;
size_low= GetFileSize(hFile,&size_high);
//创建文件的内存映射文件。
HANDLE hMapFile=CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
size_high,
size_low,
NULL);
//把文件数据映射到进程的地址空间
(PBYTE) pvFile = (PBYTE)MapViewOfFile(
hMapFile,
FILE_MAP_READ,
0,
0,
0);
------
MapViewOfFile可以指定偏移量
这个用ReadFile就行了,不要看到大文件就想着CreateFileMapping
------
CreateFileMapping函数设置映射区大小后。
通过MapViewOfFile函数的第三和第四个参数来指定高低偏移量。第5个参数指定要映射的字节数:
------
谢谢二位的回答,可以简单写个例子吗?谢谢了
------
(PBYTE) pvFile = (PBYTE)MapViewOfFile(
hMapFile,
FILE_MAP_READ,
0, // 偏移量的高32位
0, // 偏移量的低32位 必须是CPU粒度的整数倍
0); // 视图大小 这里就是10000了 必须是CPU粒度的整数倍
------
DWORD size_low,size_high;
size_low= GetFileSize(hFile,&size_high);
无法得到12G这么大的值,也就是说我在CreateFileMapping时,无法将该文件全部映射到内存中。
请问Lactoferrin 用ReadFile如何实现从第100亿个字节处读取10000个字节?
------
不共享的话,就用ReadFile吧
------
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);
typedef struct _OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
};
PVOID Pointer;
};
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
Offset和OffsetHigh就是偏移
------
DWORD size_low,size_high;
size_low= GetFileSize(hFile,&size_high);
INT64 最大为0xFFFFFFFFFFFFFFFF都多少了??还没有12G大?
size_low= GetFileSize(hFile,&size_high);
得到的是一个64位的值,,高32位在size_high,低32位在size_low.
------
建议使用GetFileSizeEx
------
DWORD无法存放100亿吧?DWORD是unsigned long类型的,在32位下最大是2的32次方-1比100亿小
------
MapViewOfFile的偏移是分成两个参数的,实际上是64位整数
------
0, // 偏移量的高32位
0, // 偏移量的低32位 必须是CPU粒度的整数倍
请问yaojun2偏移量的高32和低32位如何获取?还有 CPU粒度的整数倍是什么意思呢?
------
------
呵呵,大家可以详细举例说明吗?就用我问题中的数值为例,谢谢大家了
------
页的整数倍,就是4096,你可以不提供整数倍的,它会自动改成整数倍
------
请问大家可否给个一楼中的问题中的数据的具体例子?有点模糊,谢谢大家了,内存映射的参数值不知道怎么填写
------
LARGE_INTEGER a;
a.QuadPart=100亿;
dwFileOffsetLow传a.LowPart
dwFileOffsetHigh传a.HighPart
------
HANDLE hFile=CreateFile(。。。。);
DWORD dwFileSizeHigh;
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) < < 32);
//看这里,qwFileSize是64位,
//dwFileSizeHigh是文件是高32位
//dwFileSizeHigh强制转换成64位后,然后右移32位,与上GetFileSize返回的低32位值,
//就是一个64位表示的文件大小了 难道还不够12G??????
HANDLE hMap=CreateFileMapping(hFile,PAGE_READ,高32位,低32位,NULL);
PBYTE pBuf=(PBYTE)MapViewOfFile(
hMap,
FILE_MAP_READ,
0x2, //偏移量的高32位
0x540BE400, //偏移量的低32位 如果是100亿的话,就是0x2540BE400,,那么高位就是0x2,低位就是0x540BE400
10000 //这里就是粒度的整数,写10000,系统会向上取整。别管粒度是啥了。
);
------
谢谢各位的鼎力相助,我在VC6.0下运行了yaojun2提供的代码,运行后,qwFileSize是负数
------
你这样
LARGE_INTEGER size;
GetFileSizeEx(hFile,&size);
------
GetFileSizeEx需要什么头文件?我这不识别这个API
------
我操作系统是XP的
------
windows2000就有了
你头文件过老
------
我也装SP5升级包了,请问我需要在哪更新我的头文件呢
------
安装vc2010
------
《windows核心编程》里面有映射文件一部分到内存的例子。当然,楼主读取指定文件的1000字节,使用ReadFile应该是最方便的办法。
------
能否给个ReadFile的例子说明通过ReadFile如何从指定位置开始读取10000字节的内容?
------
overlapped里面指定
------
Lactoferrin,用ReadFile没有得到值,得到的返回内存信息为空。
刚用 __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);得到了文件的高位和低位,但是在设置MapViewOfFile时,返回值为空。设置如下:
//创建文件的内存映射文件。
HANDLE hMapFile=CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
size_high,
size_low,
NULL);
//把文件数据映射到进程的地址空间
(PBYTE) pvFile = (PBYTE)MapViewOfFile(
hMapFile,
FILE_MAP_READ,
(DWORD)(nOffSet>>32),
(DWORD)(nOffSet & 0xFFFFFFFF),
10000);
pvFile 为空,请问这是为什么?哪里出错了?
------
你怎么调用的ReadFile
------
OVERLAPPED tempOverLapp ;
LARGE_INTEGER size ;
size.QuadPart = nOffSet ;
tempOverLapp.Offset = size.LowPart;
tempOverLapp.OffsetHigh = size.HighPart;
char* strByte = new char[nLen+1] ;
memset(strByte,'\0',nLen+1);
unsigned long* nReadLen = new unsigned long;
ReadFile(hFile,strImage,nLen,nReadLen,&tempOverLapp);
------
终于弄出来了,原来低位是需要64K的整数倍,开心啊,哈哈
------
tempOverLapp中的其它成员也要设置好
------
tempOverLapp中的其他成员怎么设置呢?请赐教
------
如果没有特别需求,Pointer 和hEvent要设为0
------
NTSTATUS NtReadFile(
__in HANDLE FileHandle,
__in_opt HANDLE Event,
__in_opt PIO_APC_ROUTINE ApcRoutine,
__in_opt PVOID ApcContext,
__out PIO_STATUS_BLOCK IoStatusBlock,
__out PVOID Buffer,
__in ULONG Length,
__in_opt PLARGE_INTEGER ByteOffset,
__in_opt PULONG Key
);
------
学习。
------
目前属于打酱油的飘过....
桂ICP备07017180号