본문 바로가기

Programming/MFC

CFile 클래스

출처 웃어라. 웃음은 즐거움이다. | 오렌지
원문 http://blog.naver.com/popo1008/20008968622

CFile 클래스...
.

 

윈도우즈에서 파일 입출력에 대한 처리방법은 여러가지가 있는데, 가장 쉬
운방법은 MFC 클래스 라이브러리에서 기본적으로 제공되고 있는 표준 다이
얼로그 박스(Common Dialog Box)클래스를 이용하는 것입니다. 표준 다이얼
로그 박스는 문자열의 검색과 치환, 색상의 선택, 폰트의 선택, 프린팅에
대한 기능들도 표준 다이얼로그 박스 클래스로 제공되고 있기 때문에 이러
한 기능들을 프로그램에 지원하고자 할 때는 표준 다이얼로그 박스를 이용
하는 것이 훨씬 용이합니다.

Visual C++은 윈도우즈 상에서 보다 효율적으로 파일처리를 할 수 있도록
CFile 클래스와 직렬화(Serialization)기능을 제공하고 있습니다.

CFile 클래스

MFC는 표준 파일 처리를 위해 CFile 클래스를 제공하고 있습니다. 이 CFile
클래스에는 파일처리를 위한 많은 멤버함수들이 포함되어 있는데, 이러한
함수들은 이전에 도스상에서 자주 다루어 보았던 함수들과 유사합니다.

 

멤버함수

의미

CFile()Abort()Duplicate()Open()Close()  Read()Write()Flush()  Seek()SeekToBegin()SeekToEnd()GetLength()SetLength() LockRange()UnlockRange() GetPosition()GetStatus()GetFileName()GetFileTitle()GetFilePath()SetFilePath() Rename()Remove()GetStatus()SetStatus()
객체 생성자.모든 경고와 에러들을 무시하고 화일을 닫는다.오브젝트 복사.파일을 연다.파일 종료 및 오브젝트 삭제. 파일로 부터 데이타를 읽는다.현재파일 위치에 데이타를 쓴다.데이타를 제거한다.     파일포인터를 이동한다.파일 포인터를 처음으로 이동한다.파일 포인터를 끝으로 이동한다.파일의 길이를 얻는다.파일의 길이를 지정한다.   파일의 일부를 락(Lock)을 건다.파일의 일부를 락에서 해제한다.  파일의 포인터를 얻는다.지정된 파일의 상태를 얻는다.선택된 파일의 파일이름을 얻는다.선택된 파일의 타이틀을 얻는다.선택된 파일의 전체 경로를 얻는다.선택된 파일의 전체 경로를 설정한다.   지정된 파일을 다른이름으로 변경한다.지정된 파일을 제거한다.지정된 파일의 상태를 얻는다.지정된 파일의 상태를 설정한다.      

 

멤버함수들을 알았으니 CFile 클래스로 파일 쓰기와 파일 읽기 예제를 보
면서 공부해 보겠습니다.

#파일쓰기 예제

void CFileioView::OnWritefile()
{
   CFile Wfile;
   if(!Wfile.Open("TestFile.txt", CFile::modeCreate :
                    CFile::modeWrite))
   {
       MessageBox("Can't Create testfile.txt !", "Warning",
                       MB_OK : MB_ICONHAND);
       return;
   }
   char* ps = new char[27];
   char* ps2 = ps;

   for(int i=0;i<26;i++)
       *ps2++ = 'A'+i;
   *ps2 = NULL;    // NULL 문자로 끝나게 한다.
   Wfile.Write(ps,27);
   Wfile.Close();
   delete ps;
}

#파일읽기 예제

void CFileioView::OnReadfile()
{
   CFile Rfile;
   if(!Wfile.Open("TestFile.txt", CFile::modeRead))
   {
       MessageBox("Can't Open testfile.txt !", "Warning",
                       MB_OK : MB_ICONHAND);
       return;
   }
   UINT FileLength = (UINT)Rfile.GetLength();

   char* ps = new char[FileLength];
   Rfile.Read(ps,FileLength);
   Rfile.Close();

   CClientDC dc(this);
   dc.TextOut(0,0,ps,lstrlen(ps));
   delete ps;
}

마지막으로 파일의 특정위치에 데이타를 읽거나 쓸수 있도록 처리해주는
CFile 클래스의 Seek()멤버함수를 이용해보겠습니다.

#랜덤 파일 처리 예제

void CFileioView::OnAddfile()
{
   CFile Afile;
   if(!Afile.Open("TestFile.txt", CFile::modeRead :
                    CFile::modeWrite))
   {

       MessageBox("Can't Create testfile.txt !", "Warning",
                       MB_OK : MB_ICONHAND);
       return;
   }
   Afile.Seek(-1,CFile::end);
   ~~~~~~~~~~~~~
   char* ps = new char[27];
   char* ps2 = ps;
   for(int i=0;i<26;i++)
       *ps2++ = 'a'+i;
   *ps2 = NULL;    // NULL 문자로 끝나게 한다.
   Wfile.Write(ps,27);
   Wfile.Close();
   delete ps;
}

참고로 Seek()함수에 대해서 알아보겠습니다...

Seek()함수의 첫번째 매개 변수는 양수이면 앞쪽으로 파일포인터를 이동하
고, 음수이면 뒷쪽으로 파일포인터를 이동합니다. 두번째 매개 변수는 파일
의 첫번째 위치를 기준으로 파일포인터를 이동하고자 하면 CFile:begin 플
래그를 사용하고, 현재위치나 파일의 마지막을 기준으로 이동하고자 한다면
CFile::end 플래그를 사용하면 됩니다.
CFile 클래스는 이 함수 외에도 SeekToBegin()와 SeekToEnd()함수를 제공
하고 있습니다.

 

이번엔 파일의 예외처리에 대해서 알아보겠습니다...

⊙ 예외처리(Exception Handling)

MFC는 파일예외처리를 위해서 CFileException 클래스를 제공하고 있습니다
CFileException 클래스는 파일을 오픈하면서 발생되는 여러가지 에러에 관
련된 정보를 포함하고 있습니다.
파일처리에 있어서 발생되는 에러는 CFileException 클래스의 m_cause 데
이타 멤버의 값을 참조하게 됩니다. 파일 에러가 발생했을때 m_cause데이타
멤버에 발생된 에러코드가 들어가게 되는데, 이것들에는 다음과 같은 것들
이 있습니다.

   에러코드

nonegenericfileNotFoundbadPathtooManyOpenFilesaccessDeniedinvalidFileremoveCurrentDirdirectoryFullbadSeekhardIOsharingViolationlockViolationdiskFullendOfFile
에러가 없다일반적인 에러파일이 존재하지 않는다파일 경로가 맞지 않다허용된 파일 오픈 수를 넘었다파일 접근 금지파일에 이상이 있다현재 디렉토리를 제거할 수 없다디렉토리가 모두 찼다파일 포인터 지정에러하드웨어 에러SHARE.EXE가 로드되지 않았거나 공유된 지역에 락이 걸렸을 경우이미 락이 걸려 있는 지역에 락을 시도했다디스크가 모두 찼다파일의 끝에 도달하였다

 

실행에러 즉, 예외처리를 하는 TRY, CATCH, END_CATCH 매크로가 사용됩니
다. 이들 매크로는 메모리(CMemoryException), 리소스(CResourceException)
, OLE(COleException)등에 관련된 예외처리를 담당합니다.

예>
    // example for CFileException::m_cause
    extern char* pFileName;
    TRY
    {
         CFile f(pFileName, CFile::modeCreate : CFile::modeWrite);
    }
    CATCH(CFileException, e)
    {
         if(e->m_cause == CFileException::fileNotFound)
                                          ??????
              printf("ERROR : File not found\n");
    }

이번엔 switch ~ case 문으로 해볼까요?

    extern char* pFileName;

    TRY
    {
         CFile f(pFileName, CFile::modeCreate : CFile::modeWrite);
    }

    CATCH(CFileException, e)
    {
         switch(e->m_cause)
         {
              case CFileException::fileNotFound :
                                   ??????
                   MessageBox("File not found");
                   break;
              case CFileException::diskFull :
                                   ????
                   MessageBox("Disk is full");
                   break;
                   :
                   :
         }

    }