ファイルのメモリマッピング(WinAPI: 読込み専用)

WinAPI によるファイルのメモリマッピングの例です.ファイルの内容をメモリッピングした後,その先頭部の表示を行います.

ファイルのメモリマッピング(WinAPI: 読込み専用)(list_83.c)
#include <stdio.h>
#include <unistd.h>
#include <windows.h>

HANDLE mmFh;        // ファイルのハンドル
HANDLE mmhMap;      // メモリマップドファイルのハンドル
LPVOID mmhMapView;  // ファイルのビューへのポインタ

//-----------------------------------------------------------------
void usage(char* cmd);
void myhead(char* infile,int n_output,int n_fold);
LPVOID mmap_open(char* name,DWORD* filesizep);
void mmap_close(LPVOID mmapAddr);
//-----------------------------------------------------------------

int main(int argc, char* argv[])
{
    int i;
    static int n_output=10,n_fold=0;
    char *in_file=NULL;
    // read argument
    for(i=1;i<argc;i++){
        if(argv[i][0] == '-'){
            switch(argv[i][1]){
            case 'n':
                if(argv[++i] == NULL){
                    fprintf(stderr,"Output number err.\n");
                    usage(argv[0]);
                    return 0;
                }
                n_output = atoi(argv[i]);
                break;
            case 'f':
                if(argv[++i] == NULL){
                    fprintf(stderr,"Fold number not err.\n");
                    usage(argv[0]);
                    return 0;
                }
                n_fold = atoi(argv[i]);
                break;
            default:
                fprintf(stderr,"Unknown option '%c'\n",argv[i][1]);
                usage(argv[0]);
                return 0;
            }
        } else {
            in_file = argv[i];
        }
    }
    if(in_file == NULL){
        usage(argv[0]); return 0;
    }

    myhead(in_file,n_output,n_fold);
    
    return 0;
}

void usage(char* cmd)
{
    printf("usage: %s in_file [option]\n",cmd);
    printf("[option]:\n");
    printf("  -n number: set output line number\n");
    printf("  -f number: set fold number\n");
}

//------------------------------------------------------------
// ファイル先頭部の表示
//------------------------------------------------------------
void myhead(char* infile,int n_output,int n_fold)
{
    DWORD size;
    char* file_address;
    char c,old_c;
    long ri,n_byte,n_line;
    
    file_address = (char*)mmap_open(infile,&size);
    if(file_address == NULL) {
        perror(infile);
        return;
    }
    
    // output head
    ri = n_byte = n_line = 0;
    while(n_line < n_output){
        if(ri >= size) break;
        c = file_address[ri];
        old_c = c;
        if(c != '\7') write(1,&c,1);
        if(c == '\n' || (n_fold && ++n_byte >= n_fold)){
            n_byte = 0; n_line++;
            if(c!='\n'){
                old_c = '\n';
                write(1,"\n",1);
            }
        }
        ri++;
    }
    if(old_c != '\n') write(1,"\n",1);

    mmap_close(file_address);
}

//-----------------------------------------------------------------
// メモリマップドファイルの生成
//-----------------------------------------------------------------
LPVOID mmap_open(char* name,DWORD* filesizep)
{
    LPVOID addr;
    // ファイルのオープン
    mmFh = CreateFile(name,GENERIC_READ,0,NULL,OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,NULL);
    // メモリマップドファイルの生成
    mmhMap = CreateFileMapping(mmFh,NULL,PAGE_READONLY,0,0,NULL);
    if(mmhMap == NULL){
        CloseHandle(mmFh);
        perror(name);
        return NULL;
    }
    // プロセス内のアドレス空間にファイルのビューをマップ
    addr = MapViewOfFile(mmhMap,FILE_MAP_READ,0,0,0);

    *filesizep = GetFileSize(mmFh,NULL); //under 4G
    return addr;
}

//-----------------------------------------------------------------
// ファイルのビューをアンマップしマップのハンドルをクローズ
//-----------------------------------------------------------------
void mmap_close(LPVOID mmapAddr)
{
    UnmapViewOfFile(mmapAddr);
    CloseHandle(mmhMap);
    CloseHandle(mmFh);
}

result
Gami[108]% ./list_83.exe
usage: ./list_83 in_file [option]
[option]:
  -n number: set output line number
  -f number: set fold number
Gami[109]% ./list_83.exe list_83.c
#include 
#include 
#include 

HANDLE mmFh;        // ファイルのハンドル
HANDLE mmhMap;      // メモリマップドファイルのハンドル
LPVOID mmhMapView;  // ファイルのビューへのポインタ

//-----------------------------------------------------------------
void usage(char* cmd);
Gami[110]%
inserted by FC2 system