请问大家,用内存映射如何读取一个12G大小的二进制文件,我想从文件的第100亿个字节处读取10000个字节,请问大家该如何实现?
解决方案 »
- 下面画图的代码有什么问题么?
- 如何将一个文件夹里的文件组织成xml描述信息
- 如何把向导生成的Toolbar删除掉!
- 求《VISUAL C++/TURBO C串口通讯编程实践》源码光盘
- 也许是个小问题,但是极度让人郁闷的Dll问题,大家见招!
- 讨论vc++的书那本不错,请过来人指点迷津!
- 请问怎么把csdn上的文章保存到本地啊。
- 给分帖:sam1111 进来(为什么我现在只能最多给100分?怪事)
- 带有菜单的单文档程序是否可以使用快捷键或回调函数?
- 为避免图象重画时闪烁要使用双缓冲,请问怎样使用?
- listctr中创建的Combox为什么不显示下拉列表。
- 非牛勿进,非客户区(nc)自绘遇到问题。
//获得文件句柄
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);
这个用ReadFile就行了,不要看到大文件就想着CreateFileMapping
通过MapViewOfFile函数的第三和第四个参数来指定高低偏移量。第5个参数指定要映射的字节数:[code]
//创建文件的内存映射文件。
HANDLE hMapFile=CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
size_high,
size_low,
NULL); //把文件数据映射到进程的地址空间
(PBYTE) pvFile = (PBYTE)MapViewOfFile(
hMapFile,
FILE_MAP_READ,
0, //偏移量的高32位
0, //偏移量的低32位 高低组合100亿的偏移 必须是CPU粒度的整数倍
0); //要映射的字节数 这里就是10000了,,,必须是CPU粒度的整数倍[/code]
hMapFile,
FILE_MAP_READ,
0, // 偏移量的高32位
0, // 偏移量的低32位 必须是CPU粒度的整数倍
0); // 视图大小 这里就是10000了 必须是CPU粒度的整数倍
size_low= GetFileSize(hFile,&size_high);
无法得到12G这么大的值,也就是说我在CreateFileMapping时,无法将该文件全部映射到内存中。
请问Lactoferrin 用ReadFile如何实现从第100亿个字节处读取10000个字节?
__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就是偏移
size_low= GetFileSize(hFile,&size_high); INT64 最大为0xFFFFFFFFFFFFFFFF都多少了??还没有12G大?size_low= GetFileSize(hFile,&size_high);
得到的是一个64位的值,,高32位在size_high,低32位在size_low.
0, // 偏移量的低32位 必须是CPU粒度的整数倍
请问yaojun2偏移量的高32和低32位如何获取?还有 CPU粒度的整数倍是什么意思呢?
前个问题可以使用位操作后个问题 好像是64K吧 , 可以使用GetSystemInfo获得,核心编程里面有讲到
a.QuadPart=100亿;
dwFileOffsetLow传a.LowPart
dwFileOffsetHigh传a.HighPart
DWORD dwFileSizeHigh;
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
/////////////////////////////////////////////////////////////////////////
// MapViewOfFile函数:第三个参数和第四个参数的组合,为映射开始处文件偏移量,该偏移量必须为与系统内存分配尺寸相匹配的偏移量。如从第100亿个字节开始,就把100亿这个数值分解给第3、4参数的高低偏移量。// 第五个参数:指定要映射文件的字节数。如果为0,则整个文件都被映射。1000字节
__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,系统会向上取整。别管粒度是啥了。
);
LARGE_INTEGER size;
GetFileSizeEx(hFile,&size);
你头文件过老
//创建文件的内存映射文件。
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 为空,请问这是为什么?哪里出错了?
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);
__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
);
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
确实 很多方法。可以使用 GetFileSize
char* buffer = new char[10000];
CFile f;
f.Open("文件名",CFile::modeRead);
f.Seek(len,CFile::begin);
f.Read(buffer,10000);
...
f.Close();
delete [] buffer;
你要是非用内存映射你回下我告诉你。
//从文件12G.dat的第100亿个字节处读取10000个字节
#include <io.h>
#include <stdio.h>
char buf[10000];
int fh;
__int64 offset;
void main() {
fh=_open("12G.dat",_O_BINARY|_O_RDONLY);
if (fh>=0) {
if (10000000000i64==_lseeki64(fh,10000000000i64,SEEK_SET)) {
if (10000==_read(fh,buf,10000)) {
printf("OK to read 10000 bytes from offset 10000000000 of file 12G.dat.\n");
}
}
_close(fh);
}
}
__int64 offset;
是多余的。