대용량의 파일 순식간에 읽기


1.요약

10M 이상이 되는 파일을 빠르게 읽는 방법을 알아보기로 합니다.


2.본문

<대용량 파일 읽기 (빠르게...)>
v 파일 읽기는 자주 사용하실 것인데.. CFile::Read를 사용하면.. 10MB정도 되는 파일을 읽으면 무진장 오래 걸려서.. 메모리 맵 파일을 이용한 파일 읽기 방법을 올려 들립니다..

많은 예제가 나온것으로 알지만.. 혹시... 도 몰라서..



BOOL OpenFiles(LPCSTR lpszPathName) 

{ 

    DWORD dwFileSize; 

    HANDLE hFile, hFileMap; 

    LPVOID lpvFile; 

    

    hFile = ::CreateFile(lpszPathName, GENERIC_READ , 0, NULL 

        OPEN_EXISTING, FILE_ATTRIBUTTE_NORMAL, NULL); 

    if(hFile == INVALID_HANDLE_VALUE) { 

        //여기에서 에러 메세지 처리.. 

    } 

    dwFileSize = ::GetFileSize(hFile, NULL); 

    

    hFileMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 

        dwFileSize, NULL); 

    

    if(hFileMap == NULL) { 

        CloseHandle(hFile); 

        //여기에서 에러 메세지 처리.. 

    } 

    

    lpFile = MapViewOfFile(hFileMap, FILE_MAP_COPY, 0,0,0); 

    

    if(lpFile == NULL) { 

        CloseHandle(hFile); 

        CloseHandle(hFileMap); 

        //여기에서 에러 처리 

    } 

} 

이렇게 하면.. 대용량의 파일을 빠르게 읽을 수 있습니다..

제가 시간을 한번 제어 봤는데.. 4초 안에 끊나더군요..

흠.. 그리고 여기에 나온 함수는 Help에서 정확한 내용을 보세요.

.
<대용량 파일 빠르게 읽기 2>

메모리 맵파일을 이용한 방법외에 간단한 방법이 있어서 말씀드려볼까 합니다.

어려운 루틴은 아니고요, 그냥 도스용 시절에 사용했던 fread함수를 사용한 것입니다.

물론 fread대신 다른 파일 읽기 함수를 사용해도 됩니다.

다만 사용자 편의를 위해서 추가로 만들어진 파일함수들은(파일함수뿐만 아니라 다른 것들도 마찬가지...) 사용하긴 편하겠지만, 속도가 무척 느린 문제가 있습니다.

char *ReadFile( char *FileName ) 

{ 

    FILE *fp; 

    int FileSize; 

    char *buffer; 

    

    try { 

        fp = fopen( FileName, "rb" ); 

        if( !fp ) throw "File Not Found!"; 

        

        FileSize = filelength( fileno(fp) ); 

        buffer = new char [FileSize+1]; 

        fread( buffer, FileSize, 1, fp ); 

        *(buffer + FileSize) = 0; 

        fclose( fp ); 

        return buffer; 

    } 

    catch( char *msg ) { 

        printf( msg ); 

        return NULL; 

    } 

} 

위의 try ~ catch구분은 중요한것은 아니고요, 대부분의 프로그래머분들이 예외처리를 함에 있어서 일반적인 C스타일로 일일히 에러메시지를 코딩하더군요.

그래서 혹시나 도움이 될까 해서 try ~ catch구분을 사용해보았습니다. 어려운건 아니니깐 try ~ catch를 사용하면 코딩이 훨씬 간단해질꺼예요. ^^

그리고 위의 파일읽기 함수를 fopen/fread등을 사용했는데, 이건 C를 시작하는 분들 께 조금이나마 이해가 쉽도록 도스에서 사용하던 함수를 사용했습니다. 물론 이 함수들은 윈도우즈에서도 그대로 사용할수 있습니다.

원래 도스에서 fread는 한블럭최대크기가 64k로 제한됩니다.

따라서 64k씩 나누어서 파일을 읽어들여야 하는데, 윈도우즈에서는 그냥 한번에 읽을 수 있더군요. ^^

10메가 정도 읽어들이는데 있어서, 펜133의 컴에서 약 3초미만으로 걸리는 것 같습니다.



- 2001.08.13 Smile Seo -