请问大家,用内存映射如何读取一个12G大小的二进制文件,我想从文件的第100亿个字节处读取10000个字节,请问大家该如何实现?

解决方案 »

  1.   

    无需内存映射,用ReadFile加上偏移就行
      

  2.   

    我的读取方式如下:
    //获得文件句柄
    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);  
      

  3.   

    MapViewOfFile可以指定偏移量
    这个用ReadFile就行了,不要看到大文件就想着CreateFileMapping
      

  4.   

    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]
      

  5.   

    (PBYTE) pvFile = (PBYTE)MapViewOfFile(
    hMapFile,   
    FILE_MAP_READ,   
    0,     //   偏移量的高32位
    0,     //   偏移量的低32位   必须是CPU粒度的整数倍
    0);    //   视图大小   这里就是10000了      必须是CPU粒度的整数倍
      

  6.   

    DWORD size_low,size_high;
    size_low= GetFileSize(hFile,&size_high);   
    无法得到12G这么大的值,也就是说我在CreateFileMapping时,无法将该文件全部映射到内存中。
    请问Lactoferrin 用ReadFile如何实现从第100亿个字节处读取10000个字节?
      

  7.   

    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就是偏移
      

  8.   

    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.
      

  9.   

    DWORD无法存放100亿吧?DWORD是unsigned long类型的,在32位下最大是2的32次方-1比100亿小
      

  10.   

    MapViewOfFile的偏移是分成两个参数的,实际上是64位整数
      

  11.   

    0, // 偏移量的高32位
    0, // 偏移量的低32位 必须是CPU粒度的整数倍
    请问yaojun2偏移量的高32和低32位如何获取?还有 CPU粒度的整数倍是什么意思呢?
      

  12.   


    前个问题可以使用位操作后个问题 好像是64K吧 , 可以使用GetSystemInfo获得,核心编程里面有讲到
      

  13.   

    LARGE_INTEGER a;
    a.QuadPart=100亿;
    dwFileOffsetLow传a.LowPart
    dwFileOffsetHigh传a.HighPart
      

  14.   

    // 得到文件尺寸
    DWORD dwFileSizeHigh;
    __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
    qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
    /////////////////////////////////////////////////////////////////////////
    // MapViewOfFile函数:第三个参数和第四个参数的组合,为映射开始处文件偏移量,该偏移量必须为与系统内存分配尺寸相匹配的偏移量。如从第100亿个字节开始,就把100亿这个数值分解给第3、4参数的高低偏移量。// 第五个参数:指定要映射文件的字节数。如果为0,则整个文件都被映射。1000字节
      

  15.   

    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,系统会向上取整。别管粒度是啥了。  
    );   
      

  16.   

    谢谢各位的鼎力相助,我在VC6.0下运行了yaojun2提供的代码,运行后,qwFileSize是负数
      

  17.   

    你这样
    LARGE_INTEGER size;
    GetFileSizeEx(hFile,&size);
      

  18.   

    GetFileSizeEx需要什么头文件?我这不识别这个API
      

  19.   

    windows2000就有了
    你头文件过老
      

  20.   

    《windows核心编程》里面有映射文件一部分到内存的例子。当然,楼主读取指定文件的1000字节,使用ReadFile应该是最方便的办法。
      

  21.   

    能否给个ReadFile的例子说明通过ReadFile如何从指定位置开始读取10000字节的内容?
      

  22.   

    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 为空,请问这是为什么?哪里出错了? 
      

  23.   

    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);
      

  24.   

    tempOverLapp中的其它成员也要设置好
      

  25.   

    tempOverLapp中的其他成员怎么设置呢?请赐教
      

  26.   

    如果没有特别需求,Pointer 和hEvent要设为0
      

  27.   

    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
    );
      

  28.   

    DWORD dwFileSizeHigh;
        __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
        qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
    确实 很多方法。可以使用 GetFileSize
      

  29.   

    简单问题不要复杂化,就是一个读文件的问题。LONGLONG len = 100亿;
    char* buffer = new char[10000];
    CFile f;
    f.Open("文件名",CFile::modeRead);
    f.Seek(len,CFile::begin);
    f.Read(buffer,10000);
    ...
    f.Close();
    delete [] buffer;
    你要是非用内存映射你回下我告诉你。
      

  30.   

    SetFilePointerEx就搞定.. 用LargeIntger. 突破4G. 达到0xFFFFFFFF*0xFFFFFFFF的最大字节大小
      

  31.   

    没必要用内存映射!
    //从文件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);
        }
    }
      

  32.   

    上帖代码中
    __int64 offset;
    是多余的。
      

  33.   

    你的要求和读1M的文件差不多,自己写的小例子测一下就好windows下,打开文件并不等于把文件读入内存
      

  34.   

    FileMap 如果多次读写的话若是 只读一次, ReadFile 也可以
      

  35.   

    你的要求和读1M的文件差不多,自己写的小例子测一下就好windows下,打开文件并不等于把文件读入内存
      

  36.   

    对于这么大的数据用内存映射并不是什么好事,尽量已经知道偏移和数据的大小了,那么直接设置指针位置然后ReadFile就好了
      

  37.   

    需内存映射,用ReadFile加上偏移就行
      

  38.   

    本人做了一个网址导航 大家帮忙分析一下这个网站那里需要修改的 www.26552.com
      

  39.   

    不知道,这个用.NET的框架怎么做!