使用内存映射文件处理大文件示例

前面我们讲过内存映射文件的使用,但是,如果文件大小超过内存大小那怎么办呢
其实,我们在把内存映射文件映射到进程的地址空间时,可以映射一部分,通过一个循环,把整个文件处理完

下面我举个例子

#include <windows.h>
#include <iostream>
#include <stdio.h>
using namespace std;
__int64 Count0s();
int main()
{
    __int64 co=Count0s();
    //cout<<co<<endl;
    printf("%I64u",co);
    system("pause");
    return 0;
}

__int64 Count0s()
{
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    //打开数据文件
    HANDLE hFile=CreateFile("FuncMan.dat",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    if(hFile==INVALID_HANDLE_VALUE)
    {
        cout<<"打开文件失败"<<endl;
        return 0;
    }
    //创建文件映射对象
    HANDLE hFileMap=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
    if(hFileMap==NULL)
    {
        CloseHandle(hFile);
        cout<<"创建文件映射对象失败"<<endl;
        return 0;
    }
    //获取文件大小
    DWORD FileSizeHigh,FileSizeLow;
    FileSizeLow=GetFileSize(hFile,&FileSizeHigh);
    //在这里如果想要获取超过4GB文件的大小
    __int64 FileSize=FileSizeLow+(FileSizeHigh<<32);
    CloseHandle(hFile);
    __int64 FileOffSet=0,NumOf0s=0;
    DWORD dwBytesInBlock;
    while(FileSize>0)
    {
        dwBytesInBlock=si.dwAllocationGranularity;
        if(FileSize<si.dwAllocationGranularity)
        {
            dwBytesInBlock=(DWORD)FileSize;
        }
        PBYTE pbFile=(PBYTE)MapViewOfFile(hFileMap,FILE_MAP_READ,(DWORD)(FileOffSet>>32),(DWORD)(FileOffSet&0xFFFFFFFF),dwBytesInBlock);
        for(DWORD dwByte=0;dwByte<dwBytesInBlock;dwByte++)
        {
            if(pbFile[dwByte]==0)
            {
                NumOf0s++;
            }
        }
        UnmapViewOfFile(pbFile);
        FileOffSet+=dwBytesInBlock;
        FileSize-=dwBytesInBlock;
    }
    CloseHandle(hFileMap);
    return NumOf0s;
}

这里需要注意的是文件的位移一定需要是分配粒度的倍数,所以,当所剩的大小大于分配粒度时 dwBytesInBlock等于分配粒度,否则等于文件剩下的大小

测试结果:
4796

猜你喜欢

转载自blog.csdn.net/baidu_25539425/article/details/78982072