急!急!急! 内存映射文件问题
我用内存映射文件加快读取大文件的速度,因文件很大,所以我分块映射,结果,读取的数字不正确,为什么?
代码如下:
......
Qt::HANDLE hFile;
Qt::HANDLE hMapFile;
quint8 * lpwFileAddr;
hFile = CreateFile( fileName.utf16() , GENERIC_READ,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
QMessageBox::warning( 0, "aaa1", QString::fromLocal8Bit("创建文件对象失败,错误代码") );
return false;
}
hMapFile= CreateFileMapping(hFile,NULL, PAGE_READONLY,0,0,NULL);
if ( hMapFile==NULL )
{
QMessageBox::warning( 0, "aaa2", QString::fromLocal8Bit("创建文件映射对象失败,错误代码") );
return false;
}
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
DWORD dwAllocationGranularity = sinf.dwAllocationGranularity;
quint64 offset=dwAllocationGranularity*1024;
quint64 qwFileOffset=0;
lpwFileAddr=(quint8 *)MapViewOfFile(hMapFile,FILE_MAP_READ, 0, qwFileOffset,offset);
if ( lpwFileAddr == NULL )
{
QMessageBox::warning( 0, "aaa3", QString::fromLocal8Bit("创建文件映射对象失败,错误代码") );
return false;
}
memcpy( &recNum, lpwFileAddr +3608, sizeof( Q_INT32 ) );
....
当我打印recNum时,发现它的值为16777216,这个值是不对的,应该是210,不知道为什么?
[解决办法]
楼主估计是地址偏移搞错了,认真分析一边吧
[解决办法]
memcpy( &recNum, lpwFileAddr +3608, sizeof( Q_INT32 ) );
应该是这句话错了,从当前映射文件的3KB 开始复制,赋值的大小是sizeof( Q_INT32 ) ,给recNum,
所以计算的文件大小就是sizeof( Q_INT32 ),
顺便问下楼主是怎么计算recNum?
[解决办法]
仅供参考
#include <sys\stat.h>#include <io.h>#include <fcntl.h>#include <share.h>#include <stdlib.h>#include <stdio.h>#include <conio.h>#include <string.h>#define MAX_CLU_BYTES 65536FILE *fo;int fh;__int64 offs,offs1;__int64 rvi64;int rv,wrv;unsigned char buf[MAX_CLU_BYTES];char ofn[_MAX_PATH];void main(int argc,char **argv) { if (argc<3) { printf("Copy File Tail.\n"); printf("Usage:\n"); printf(" cft filename.ext offset_begin[-offset_end]\n"); printf("Copy filename.ext offset_begin[-offset_end] to offset_begin[-offset_end]-filename.ext\n"); printf("Note: Byte at offset_end is NOT included.\n"); printf("Example:\n"); printf(" cft abc.rar 12345\n"); printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n"); printf(" cft abc.rar 123-12345\n"); printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n"); printf(" cft abc.rar 0xAB-0xCD\n"); printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n"); return; } rv=sscanf(argv[2],"%I64i-%I64i",&offs,&offs1); if (rv==0) { printf("offset %s is not number\n",argv[2]); return; } fh=_sopen(argv[1],_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYWR); if (fh==-1) { printf("_sopen %s errno=%d\n",argv[1],errno); return; } if (rv==1) { offs1=_filelengthi64(fh); if (offs1==-1i64) { printf("%I64=_filelengthi64 errno=%d\n",offs1,errno); _close(fh); return; } } else {//rv==2 if (offs1<offs) { printf("%s offset_begin>offset_end error\n",argv[2]); _close(fh); return; } } rvi64=_lseeki64(fh,offs,SEEK_SET); if (rvi64!=offs) { printf("%I64u=_lseeki64 %I64u errno=%d\n",rvi64,offs,errno); _close(fh); return; } sprintf(ofn,"%s-",argv[2]); strcat(ofn,argv[1]); fo=fopen(ofn,"wb"); if (fo==NULL) { _close(fh); printf("fopen %s error\n",ofn); return; } cprintf("\n%I64u\r",offs); while (1) { rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES)); if (rv==0) break;// if (rv<0) { fclose(fo); _close(fh); printf("_read %s offset %I64u error\n",argv[1],offs); return; } wrv=fwrite(buf,1,rv,fo); if (wrv!=rv) { fclose(fo); _close(fh); printf("fwrite %s error\n",ofn); return; } else { offs+=rv; cprintf("%I64u\r",offs); if (offs>=offs1) break;// } } fclose(fo); _close(fh); printf("Copy %s offset %s to %s OK.\n",argv[1],argv[2],ofn);}
[解决办法]
读开始字节都不对,到后面肯定更不对啊;
先从简单的调试一下看看。
HANDLE hFile=CreateFile("c:\\mapping.txt", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFilemap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 100, // 只是?辟100个 NULL); LPVOID pVoid=MapViewOfFile(hFilemap,FILE_MAP_ALL_ACCESS,0,0,0); char chDat[100]; memcpy(chDat, pVoid, 6); // char *Buf=(char *)pVoid; // // Buf[0]='T'; CloseHandle(hFile); CloseHandle(hFilemap); UnmapViewOfFile(pVoid);