MFC讀寫文件詳解


1.CFile類提供了對文件進行打開,關閉,讀,寫,刪除,重命名以及獲取文件信息等文件操作的基本功能,足以處理任意類型的文件操作。

  雖然使用CArchive類內建的序列化功能是保存和加載持久性數據的便捷方式,但有時在程序中需要對文件處理過程擁有更多的控制權,對於這種文件輸入輸出(I/O)服務

的需求,Windows提供了一系列相關的API函數,並由MFC將其封裝為CFile類,提供了對文件進行打開,關閉,讀,寫,刪除,重命名以及獲取文件信息等文件操作的基本功

能,足以處理任意類型的文件操作。CFile類是MFC文件類的基類,支持無緩沖的二進制輸入輸出,也可以通過與CArchive類的配合使用而支持對MFC對象的帶緩沖的序列化。

  CFile類包含有一個公有型數據成員m_hFile,該數據成員包含了同CFile類對象相關聯的文件句柄。如果沒有指定句柄,則該值為CFile::hFileNull。由於該數據成員所包含的

意義取決於派生的類,因此一般並不建議使用m_hFile。

  通過CFile類來打開文件可以采取兩種方式:一種方式是先構造一個CFile類對象然后再調用成員函數Open()打開文件,另一種方式則直接使用CFile類的構造函數去打開

一個文件。下面的語句分別演示了用這兩種方法打開磁盤文件“C:/1.txt”的過程:

CFile file;

file.open("C://1.txt",CFile::modeReadWrite);

其中參數CFile::modeReadWrite是打開文件的模式標志,CFile類中與之類似的標志還有十幾個,現集中列表如下:

  文件模式標志 說明

  CFile::modeCreate  創建方式打開文件,如文件已存在則將其長度設置為0

  CFile::modeNoInherit  不允許繼承

  CFile::modeNoTruncate 創建文件時如文件已存在不對其進行截斷

  CFile::modeRead 只讀方式打開文件

  CFile::modeReadWrite 讀寫方式打開文件

  CFile::modeWrite 寫入方式打開文件

  CFile::shareCompat 在使用過程中允許其他進程同時打開文件

  CFile::shareDenyNone 在使用過程中允許其他進程對文件進行讀寫

  CFile::shareDenyRead 在使用過程中不允許其他進程對文件進行讀取

  CFile::shareDenyWrite 在使用過程中不允許其他進程對文件進行寫入

  CFile::shareExclusive  取消對其他進程的所有訪問

  CFile::typeBinary 設置文件為二進制模式

  CFile::typeText 設置文件為文本模式

  這些標志可以通過“或”運算符而同時使用多個,並以此來滿足多種需求。例如,需要以讀寫方式打開文件,如果文件不存在就創建一個新的,如果文件已經存在則不將其文

件長度截斷為0。為滿足此條件,可用CFile::modeCreate、CFile::modeReadWrite和CFile::modeNoTruncate等幾種文件模式標志來打開文件:

CFile file("C://1.txt",CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate);

在打開的文件不再使用時需要將其關閉,即可以用成員函數Close()關閉也可以通過CFile類的析構函數來完成。當采取后一種方式時,如果文件還沒有被關閉,析構函數將負

責隱式調用Close()函數去關閉文件,這也表明創建在堆上的CFile類對象在超出范圍后將自動被關閉。由於調用了對象的析構函數,因此在文件被關閉的同時CFile對象也被銷

毀,而采取Close()方式關閉文件后,CFile對象仍然存在。所以,在顯式調用Close()函數關閉一個文件后可以繼續用同一個CFile對象去打開其他的文件。

文件讀寫是最常用的文件操作方式,主要由CFile類成員函數Read()、Write()來實現。其函數原型分別為:

UINT Read(void *lpBUF,UINT nCount);

void Write(const void* lpBuf,UINT nCount);

參數lpBuf為指向存放數據的緩存的指針,nCount為要讀入或寫入的字節數,Read()返回的為實際讀取的字節數,該數值小於或等於nCount,如果小於nCount則說明已經讀

到文件末尾,可以結束文件讀取,如繼續讀取,將返回0。因此通常可以將實際讀取字節數是否小於指定讀取的字節數或是否為0作為判斷文件讀取是否到達結尾的依據。下面這

段代碼演示了對文件進行一次性寫入和循環多次讀取的處理過程:

CFile file;  

file.Open("C://TestFile.txt", CFile::modeWrite | CFile::modeCreate);   

memset(WriteBuf, 'a', sizeof(WriteBuf));  

file.Write(WriteBuf, sizeof(WriteBuf));  

file.Close();  

file.Open("C://TestFile.txt", CFile::modeRead);  

while (true)  

{  

  int ret = file.Read(ReadBuf, 100);  

  if (ret < 100)

   break;

 }

 file.Close();  

Write()和Read()函數執行完后將自動移動文件指針,因此不必再顯示調用Seek()函數去定位文件指針。包含有文件定位函數的完整代碼如下所示:

CFile file;    

file.Open("C://TestFile.txt", CFile::modeWrite | CFile::modeCreate);      

memset(WriteBuf, 'a', sizeof(WriteBuf));    

file.SeekToBegin();    

file.Write(WriteBuf, sizeof(WriteBuf));       

file.Close();    

file.Open("C://TestFile.txt", CFile::modeRead);    

while (true)    

{      

  static int position = 0;      

  file.Seek(position, CFile::begin);    

  int ret = file.Read(ReadBuf, 100);    

  position += ret;  

   if (ret < 100)  

   break;    

}    

file.Close();

2.有了讀寫文件的功能實際操作起來就簡單起來,相當於數據庫使用。

3.CFileFind類的使用

  3.1開始查找(指定查找的目錄)

    CFileFind::FindFile(strFileName,0);  //strName為要查找的文件名,為NULL表示查找“*.*”成功返回非0,失敗返回0

  3.2查找下一個(獲取當前文件信息,返回下一個文件是否存在)

    CFileFind::FindNextFile();  //返回非0表示還有符合條件的下一個文件,返回0表示已是最后一個文件

  3.3獲取/判斷文件信息

    CFileFind::GetCreationTime();  //獲取文件的創建時間,成功返回非0,失敗返回0

      virtual BOOL GetCreationTime(FILETIME *pFileTime) const;  //FILETIME  *:容納時間的結構指針

      virtual BOOL GetCreationTime(CTime& refTime) const;  //CTime&:容納時間的對象地址

      FILETIME和CTime的相互轉換:

        FILETIME轉CTime:

          1、CTime對象在初始化時可以傳遞FILETIME結構

            FILETIME ft;

            CTime time(ft);

          2、將FILETIME轉換為SYSTEMTIME,然后CTime對象在初始化時可以傳遞SYSTEMTIME結構

            FILETIME ft;

            SYSTEMTIME st;

            BOOL bSuccess=::FileTimeToSystemTime(&ft , &st);

            CTime time(st);

        CTime轉FILETIME:

          CTime time(CTime::GetCurrentTime());

          SYSTEMTIME st;

          time.GetAsSystemTime(st);

          FILETIME ft;

          ::SystemTimeToFileTime(&st,&ft);

    CFileFind::GetLastAccessTime();  //獲取文件最后被訪問的時間,成功返回非0,失敗返回0

      virtual BOOL GetLastAccessTime(FILETIME *pFileTime) const;

      virtual BOOL GetLastAccessTime(CTime& refTime) const;

    CFileFind::GetLastWriteTime();  //獲取文件最后被修改的時間,成功返回非0,失敗返回0

      virtual BOOL GetLastWriteTime(FILETIME *pFileTime) const;

      virtual BOOL GetLastWriteTime(CTime& refTime) const;

    CFileFind::GetRoot();  //獲取查找到的文件的根目錄,必須在執行FindNextFile()后執行該函數,返回CString對象

    CFileFind::GetFileName();  //獲取查找到的文件的全名(包含擴展名),必須在執行FindNextFile()后執行該函數,返回CString對象

    CFileFind::GetFilePath();  //獲取查找到的文件的絕對路徑,必須在執行FindNextFile()后執行該函數,返回CString對象

    CFileFind::GetFileTitle();  //獲取查找到的文件的名稱(若系統默認隱藏文件擴展名則不顯示),必須在執行FindNextFile()后執行該函數,返回CString對象

    CFileFind::GetFileURL();  //獲取查找到的文件的URL路徑,必須在執行FindNextFile()后執行該函數,返回CString對象

    CFileFind::GetLength();  //獲取查找到的文件的長度DWORD

    CFileFind::IsArchived();  //判斷查找的文件屬性是否是檔案文件,必須在執行FindNextFile()后執行該函數,非0表示是,0表示不是

    CFileFind::IsCompressed();  //判斷查找的文件屬性是否是壓縮文件,必須在執行FindNextFile()后執行該函數

    CFileFind::IsDirectory();  //判斷查找的文件屬性是否為路徑文件(文件夾),必須在執行FindNextFile()后執行該函數

    CFileFind::IsDots();  //判斷查找的文件屬性是否是“.”、“..”,必須在執行FindNextFile()后執行該函數

    CFileFind::IsHidden();  //判斷查找的文件屬性是否為隱藏文件,必須在執行FindNextFile()后執行該函數

    CFileFind::IsNormal();  //判斷查找的文件屬性是否為正常文件,必須在執行FindNextFile()后執行該函數

    CFileFind::IsReadOnly();  //判斷查找的文件屬性是否為只讀文件,必須在執行FindNextFile()后執行該函數

    CFileFind::IsSystem();  //判斷查找的文件屬性是否為系統文件,必須在執行FindNextFile()后執行該函數

    CFileFind::IsTemporary();  //判斷查找的文件屬性是否為臨時文件,必須在執行FindNextFile()后執行該函數

    CFileFind::MatchesMask(DWORD dwMask);  //判斷查找的文件的綜合屬性,必須在執行FindNextFile()后執行該函數

      dwMask參數包括:

        FILE_ATTRIBUTE_ARCHIVE:檔案文件

        FILE_ATTRIBUTE_COMPRESSED:壓縮文件

        FILE_ATTRIBUTE_DIRECTORY:路徑文件

        FILE_ATTRIBUTE_NORMAL:正常文件

        FILE_ATTRIBUTE_READONLY:只讀文件

        FILE_ATTRIBUTE_SYSTEM:系統文件

        FILE_ATTRIBUTE_TEMPORARY:臨時文件

        FILE_ATTRIBUTE_HIDDEN:隱藏文件

  3.4結束查找

    CFileFind::Close();

4.結束疲倦的一天,明天繼續美好的生活。

                                  改變自己,從現在做起-----------久館


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM