VC++中使用內(nèi)存映射文件處理大文件(2)

字號(hào):

用內(nèi)存映射文件處理大文件應(yīng)用示例
    下面結(jié)合一個(gè)具體的實(shí)例來進(jìn)一步講述內(nèi)存映射文件的使用方法。該實(shí)例從端口接收數(shù)據(jù),并實(shí)時(shí)將其存放于磁盤,由于數(shù)據(jù)量大(幾十GB),在此選用內(nèi)存映射文件進(jìn)行處理。下面給出的是位于工作線程MainProc中的部分主要代碼,該線程自程序運(yùn)行時(shí)啟動(dòng),當(dāng)端口有數(shù)據(jù)到達(dá)時(shí)將會(huì)發(fā)出事件hEvent[0],WaitForMultipleObjects()函數(shù)等待到該事件發(fā)生后將接收到的數(shù)據(jù)保存到磁盤,如果終止接收將發(fā)出事件hEvent[1],事件處理過程將負(fù)責(zé)完成資源的釋放和文件的關(guān)閉等工作。下面給出此線程處理函數(shù)的具體實(shí)現(xiàn)過程:
    ……
    // 創(chuàng)建文件內(nèi)核對(duì)象,其句柄保存于hFile
    HANDLE hFile = CreateFile("Recv1.zip",
    GENERIC_WRITE | GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    CREATE_ALWAYS,
    FILE_FLAG_SEQUENTIAL_SCAN,
    NULL);
    // 創(chuàng)建文件映射內(nèi)核對(duì)象,句柄保存于hFileMapping
    HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,
    0, 0x4000000, NULL);
    // 釋放文件內(nèi)核對(duì)象
    CloseHandle(hFile);
    // 設(shè)定大小、偏移量等參數(shù)
    __int64 qwFileSize = 0x4000000;
    __int64 qwFileOffset = 0;
    __int64 T = 600 * sinf.dwAllocationGranularity;
    DWORD dwBytesInBlock = 1000 * sinf.dwAllocationGranularity;
    // 將文件數(shù)據(jù)映射到進(jìn)程的地址空間
    PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping,
    FILE_MAP_ALL_ACCESS,
    (DWORD)(qwFileOffset>>32), (DWORD)(qwFileOffset&0xFFFFFFFF), dwBytesInBlock);
    while(bLoop)
    {
    // 捕獲事件hEvent[0]和事件hEvent[1]
    DWORD ret = WaitForMultipleObjects(2, hEvent, FALSE, INFINITE);
    ret -= WAIT_OBJECT_0;
    switch (ret)
    {
    // 接收數(shù)據(jù)事件觸發(fā)
    case 0:
    // 從端口接收數(shù)據(jù)并保存到內(nèi)存映射文件
    nReadLen=syio_Read(port[1], pbFile + qwFileOffset, QueueLen);
    qwFileOffset += nReadLen;
    // 當(dāng)數(shù)據(jù)寫滿60%時(shí),為防數(shù)據(jù)溢出,需要在其后開辟一新的映射視圖
    if (qwFileOffset > T)
    {
    T = qwFileOffset + 600 * sinf.dwAllocationGranularity;
    UnmapViewOfFile(pbFile);
    pbFile = (PBYTE)MapViewOfFile(hFileMapping,
    FILE_MAP_ALL_ACCESS,
    (DWORD)(qwFileOffset>>32), (DWORD)(qwFileOffset&0xFFFFFFFF), dwBytesInBlock);
    }