簡介
CFile是MFC檔案類的基類,它直接提供非緩衝的二進制磁碟輸入/輸出設備,並間接地通過派生類支持文本檔案和記憶體檔案。CFile與CArchive類共同使用,支持MFC對象的串列化
該類與其派生類的層次關係讓程式通過多形CFile接口操作所有檔案對象。例如,一個記憶體檔案相當一個磁碟檔案。
使用CFile及其派生類進行一般目的的磁碟I/O,使用ofstream或其它Microsoft輸入輸出流類將格式化文本送到磁碟檔案。
通常,一個磁碟檔案在CFile構造時自動打開並在析構時關閉。靜態成員函式使你可以在不打開檔案的情況下檢查檔案狀態。
使用前包含頭檔案 #include <afx.h>
成員
數據成員
m_hFile 常包含作業系統檔案句柄
構造函式
CFile 從一個路徑或檔案句柄構造一個CFile對象;
Open 帶錯誤檢驗選項,安全打開一個檔案;
Close 關閉檔案,刪除對象。
輸入和輸出
Read 從檔案的當前位置讀數據;
ReadHuge 可從檔案的當前位置讀取大於64K數據,在32位編程中廢棄了,見Read;
WriteHuge 可將檔案的大於64K數據寫到當前檔案位置,在32位編程中廢棄了,見Write;
定位
SeekToBegin 定位當前檔案指針到檔案開頭;
SeekToEnd 定位當前檔案指針到檔案尾;
SetLength 改變檔案長度。
封鎖
UnlockRange 解鎖一定範圍內的位元組。
狀態
GetPosition 獲取當前檔案指針;
GetStatus 獲取打開檔案的狀態;
GetFilePath 獲取被選檔案的完整路徑;
SetFilePath 設定被選檔案的完整路徑
靜態
GetStatus 獲取指定檔案的狀態(靜態,虛函式); //注,此處錯誤:靜態函式不會是虛函式了。
SetStatus 設定指定檔案的狀態(靜態,虛函式) //同上
操作詳解
各種關於檔案的操作在程式設計中是十分常見,如果能對其各種操作都了如指掌,就可以根據實際情況找到最佳的解決方案,從而在較短的時間內編寫出高效的代碼,因而熟練的掌握檔案操作是十分重要的。本文將對Visual C++中有關檔案操作進行全面的介紹,並對在檔案操作中經常遇到的一些疑難問題進行詳細的分析。
檔案的查找
當對一個檔案操作時,如果不知道該檔案是否存在,就要首先進行查找。MFC中有一個專門用來進行檔案查找的類CFileFind,使用它可以方便快捷地進行檔案的查找。下面這段代碼演示了這個類的最基本使用方法。
CString strFileTitle;
CFileFind finder;
BOOL bWorking = finder.FindFile("C:\\windows\\sysbkup\\*.cab");
while(bWorking)
{
bWorking=finder.FindNextFile();
strFileTitle=finder.GetFileTitle();
}
檔案的打開
讓用戶選擇檔案進行打開和存儲操作時,就要用到檔案打開/保存對話框。MFC的類CFileDialog用於實現這種功能。使用CFileDialog聲明一個對象時,第一個BOOL型參數用於指定檔案的打開或保存,當為TRUE時將構造一個檔案打開對話框,為
FALSE時構造一個檔案保存對話框。
在構造
CFileDialog對象時,如果在參數中指定了OFN_ALLOWMULTISELECT風格,則在此對話框中可以進行多選操作。此時要重點注意為此CFileDialog對象的m_ofn.lpstrFile分配一塊記憶體,用於存儲多選操作所返回的所有檔案路徑名,如果不進行分配或分配的記憶體過小就會導致操作失敗。下面這段程式演示了檔案打開對話框的使用方法。
CFileDialog mFileDlg(TRUE,NULL,NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
"All Files (*.*)|*.*||",AfxGetMainWnd());
CString str(" ",10000);
mFileDlg.m_ofn.lpstrFile=str.GetBuffer(10000);
str.ReleaseBuffer();
POSITION mPos=mFileDlg.GetStartPosition();
CString pathName(" ",128);
CFileStatus status;
while(mPos!=NULL)
{
pathName=mFileDlg.GetNextPathName(mPos);
CFile::GetStatus( pathName, status );
}
檔案的讀寫
檔案的讀寫非常重要,下面將重點進行介紹。檔案讀寫的最普通的方法是直接使用CFile進行,如檔案的讀寫可以使用下面的方法:
//對檔案進行讀操作
char sRead[2];
CFile mFile(_T("user.txt"),CFile::modeRead);
if(mFile.GetLength()<2)
return;
mFile.Read(sRead,2);
mFile.Close();
//對檔案進行寫操作
TCHAR sWrite[]="這裡寫一竄包含中文的字元.abcd123";
BYTE sUNICODE={0xff,0xfe};
CFile mFile(_T("user.txt "), CFile::modeWrite|CFile::modeCreate);
mFile.Write(sUNICODE,sizeof(sUNICODE)); //將檔案變為UNICODE編碼
mFile.Write(sWrite,sizeof(sWrite));
mFile.Flush();
mFile.Close();
注意:如果sWrite中沒有中文等雙位元組字元,則就沒有這樣麻煩.
雖然這種方法最為基本,但是它的使用繁瑣,而且功能非常簡單。我向你推薦的是使用CArchive,它的使用方法簡單且功能十分強大。首先還是用CFile聲明一個對象,然後用這個對象的
指針做參數聲明一個CArchive對象,你就可以非常方便地存儲各種複雜的數據類型了。它的使用方法見下例。
//對檔案進行寫操作
CString strTemp;
CFile mFile;
mFile.Open("d:\\dd\\try.TRY",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
CArchive ar(&mFile,CArchive::store);
ar<<strTemp;
ar.Close();
mFile.Close();
//對檔案進行讀操作
CFile mFile;
if(mFile.Open("d:\\dd\\try.TRY",CFile::modeRead)==0)
return;
CArchive ar(&mFile,CArchive::load);
ar>>strTemp;
ar.Close();
mFile.Close();
CArchive的 << 和>> 操作符用於簡單數據類型的讀寫,對於CObject派生類的對象的存取要使用ReadObject()和WriteObject()。使用CArchive的ReadClass()和WriteClass()還可以進行類的讀寫,如:
//存儲CAboutDlg類
ar.WriteClass(RUNTIME_CLASS(CAboutDlg));
//讀取CAboutDlg類
CRuntimeClass* mRunClass=ar.ReadClass();
//使用CAboutDlg類
CObject* pObject=mRunClass->CreateObject();
((CDialog* )pObject)->DoModal();
雖然VC提供的文檔/視結構中的文檔也可進行這些操作,但是不容易理解、使用和管理,因此雖然很多VC入門的書上花費大量篇幅講述文檔/視結構,但我建議你最好不要使用它的文檔。關於如何進行文檔/視的分離有很多書介紹,包括非常著名的《Visual C++ 技術內幕》。
如果你要進行的檔案操作只是簡單的讀寫整行的字元串,我建議你使用CStdioFile,用它來進行此類操作非常方便,如下例。
CStdioFile mFile;
CFileException mExcept;
mFile.Open( "d:\\temp\\aa.bat", CFile::modeWrite, &mExcept);
CString string="I am a string.";
mFile.WriteString(string);
mFile.Close();
使用
正規軟體經常用到臨時檔案,你經常可以會看到C:\Windows\Temp目錄下有大量的擴展名為tmp的檔案,這些就是程式運行是建立的臨時檔案。臨時檔案的使用方法基本與常規檔案一樣,只是檔案名稱應該調用函式
GetTempFileName()獲得。它的第一個參數是建立此臨時檔案的路徑,第二個參數是建立臨時檔案名稱的前綴,第四個參數用於得到建立的臨時檔案名稱。得到此臨時檔案名稱以後,你就可以用它來建立並操作檔案了,如:
char szTempPath[_MAX_PATH],szTempfile[_MAX_PATH];
CFile m_tempFile(szTempfile,CFile:: modeCreate|CFile:: modeWrite);
char m_char='a';
m_tempFile.Write(&m_char,2);
m_tempFile.Close();
複製和刪除
MFC中沒有提供直接進行這些操作的功能,因而要使用SDK。SDK中的檔案相關函式常用的有CopyFile()、CreateDirectory()、DeleteFile()、MoveFile()。它們的用法很簡單,可參考MSDN。
1,判斷檔案是否存在
access(filename,mode);
2,對於不同用途又不同的檔案操作,其中API函式CreateFile()也是比較有用處理方式,對於巨型檔案很合適的其他的樓上的大都說了,不重複了.
[1]顯示對話框,取得檔案名稱
CString FilePathName;
CFileDialog dlg(TRUE);///TRUE為OPEN對話框,FALSE為S***E AS對話框
if (dlg.DoModal() == IDOK)
FilePathName=dlg.GetPathName();
相關信息:CFileDialog 用於取檔案名稱的幾個成員函式:
假如選擇的檔案是C:\WINDOWS\TEST.EXE
(2)GetFileTitle();取回TEST
(3)GetFileName();取回TEST.EXE
(4)GetFileExt();取擴展名EXE
[2]打開檔案
CFile file("C:\HELLO.TXT",CFile::modeRead);//唯讀方式打開
CFile::modeCreate 直接構造去創建一個新的檔案如果這個檔案存在,則刪除這個檔案里所有內容
CFile::modeNoTruncate 聯合創建屬性,如果這個檔案已創建,則不刪除原檔案內容,因而這個檔案是可以當做一個已經存在,或者不存在而被新建的檔案來保證打開。這是非常有意義的,例如,打開來設定一個存在或者不存在的檔案都是可以的。這個屬性對於CStdioFile也是非常好的
CFile::modeRead 打開為唯讀屬性.
CFile::modeWrite 打開為只寫屬性.
CFile::modeReadWrite 打開為讀寫屬性.
CFile::modeNoInherit 防止這個檔案來源於子進程.
CFile::shareDenyNone 在這個檔案讀寫處理之外打開這個檔案
CFile::shareDenyRead 以獨占方式打開,拒絕其他讀操作
CFile::shareDenyWrite 以獨占方式打開,拒絕其他寫操作
CFile::shareExclusive 以獨占方式打開檔案,拒絕其他讀寫操作訪問這個檔案Opens the file with exclusive mode, denying other 如果這個檔案已打開進行讀寫操作則構造失敗
CFile::shareCompat 這個屬性在 32 bit MFC是不可用的. This flag maps to CFile::shareExclusive 當套用在CFile::Open.
CFile::typeText 設定文本模式特別處理回車換行 (used in derived classes only).
CFile::typeBinary 設定二進制模式(used in derived classes only).
例子:
{
CFile file;
file.Open("C:\HELLO.TXT",CFile::modeCreate|Cfile::modeWrite);
.
.
.
}
file.Seek(100,CFile::begin);///從
檔案頭開始往下移動100位元組
file.Seek(-50,CFile::end);///從檔案末尾往上移動50位元組
file.Seek(-30,CFile::current);///從當前位置往上移動30位元組
file.SeekToBegin();///移到檔案頭
file.SeekToEnd();///移到檔案尾
[4]讀寫檔案
讀檔案:
char buffer[1000];
file.Read(buffer,1000);
寫檔案:
CString string("自強不息");
file.Write(string,8);
[5]關閉檔案
file.Close();