回 帖 发 新 帖 刷新版面

主题:急!急!急!内存映射文件

我用内存映射文件加快读取大文件的速度,因文件很大,所以我分块映射,结果,读取的数字不正确,为什么?
代码如下:


        ......

        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,不知道为什么?

回复列表 (共1个回复)

沙发

代码有几个错误,但这些错误不影响结果
错误有:1.qwFileOffset不应该是quint64类型,MapViewOfFile的第三个参数和第四个参数组合起来才是uint64类型类型
        2.MapViewOfFile的第五个参数值应该是你想map的数据大小,而不是虚拟内存的大小。应该是一个小于或等于文件总长度的值,如果你想map整个文件,可以直接给它一个0值。
瑕疵有:3.你想将3608处的值赋给recNum,根本就不需要动用memcpy,低效且丑陋。我会写成
          recNum = *(Q_INT32*)(lpwFileAddr+3608)

当然,以上的这些错误都不会使得结果出错,所以我怀疑 你不是想取第3608个字节处的INT32值,而是想取第3608个INT32处的INT32值,即代码应该是
    memcpy( &recNum, lpwFileAddr+3608*sizeof(Q_INT32), sizeof(Q_INT32) );
    或
    memcpy( &recNum, ((Q_INT32*)lpwFileAddr)+3608, sizeof(Q_INT32) );

我来回复

您尚未登录,请登录后再回复。点此登录或注册