各種關於檔案的操作在程式設計中十分常見,如果能對這些操作都了如指掌,就可以根據實際情況找到最佳的解決方案,從而可以在較短的時間內編寫出高效的代碼。本文對Visual C++中有關檔案操作進行了全面的介紹,並對在檔案操作中經常遇到的一些疑難問題進行了詳細分析。
1. 檔案的尋找
當對一個檔案操作時,如果不知道該檔案是否存在,就要首先進行尋找。MFC中有一個專門用來進行檔案尋找的類“CFileFind”,使用它可以方便快捷地進行檔案的尋找。下面這段代碼示範了這個類的最基本使用方法。
CString strFileTitle; CFileFind finder; BOOL bWorking = finder.FindFile(“C:\\windows\\sysbkup\\*.cab”); while(bWorking) { bWorking=finder.FindNextFile(); strFileTitle=finder.GetFileTitle(); } |
2. 檔案的開啟/儲存對話方塊
讓使用者選擇檔案進行開啟和儲存操作時,就要用到檔案開啟/儲存對話方塊。MFC的類“CFileDialog”用於實現這種功能。使用“CFileDialog”聲明一個對象時,第一個BOOL型參數用於指定檔案的開啟或儲存,當為TRUE時將構造一個檔案開啟對話方塊,為FALSE時構造一個檔案儲存對話方塊。
在構造“CFileDialog”對象時,如果在參數中指定了“OFN_ALLOWMULTISELECT”風格,則在此對話方塊中可以進行多選操作。此時要重點注意為此“CFileDialog”對象的“m_ofn.lpstrFile”分配一塊記憶體,用於儲存多選操作所返回的所有檔案路徑名,如果不進行分配或分配的記憶體過小就會導致操作失敗。下面這段程式示範了檔案開啟對話方塊的使用方法。
CFileDialog mFileDlg(TRUE, NULL,NULL, OFN_HIDEREADONLY|OFN_OVER WRITEPROMPT|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); } |
3. 檔案的讀寫
檔案的讀寫非常重要,下面將重點進行介紹。檔案讀寫最普通的方法是直接使用“CFile”類進行,如檔案的讀寫可以使用下面的方法:
//對檔案進行讀操作 char sRead[2]; CFile mFile(_T(“user.txt”),CFile::modeRead); if(mFile.GetLength()<2) return; mFile.Read(sRead,2); mFile.Close(); //對檔案進行寫操作 CFile mFile(_T(“user.txt”), CFile::modeWrite|CFile::modeCreate); mFile.Write(sRead,2); mFile.Flush(); mFile.Close(); |
雖然這種方法最為基本,但是它使用煩瑣,而且功能非常簡單。這裡推薦的是使用“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.Read Class(); //使用CAboutDlg類 CObject* pObject=mRunClass->CreateObject(); ((CDialog* )pObject)->DoModal(); |
雖然VC提供的文檔/視結構中的文檔也可進行這些操作,但是不容易理解、使用和管理,如果要進行的檔案操作只是簡單的讀寫整行的字串,建議使用“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(); |
4.臨時檔案的使用
正規軟體經常用到臨時檔案,經常可以看到“C:\Windows\Temp”目錄下有大量的副檔名為“.tmp”的檔案,這些就是程式運行時建立的臨時檔案。臨時檔案的使用方法基本與常規檔案一樣,只是檔案名稱應該調用函數GetTempFileName()獲得。它的第一個參數是建立此臨時檔案的路徑,第二個參數是建立臨時檔案名稱的首碼,第四個參數用於得到建立的臨時檔案名稱。得到此臨時檔案名稱以後,就可以用它來建立並操作檔案了,如:
char szTempPath[_MAX_PATH],szTempfile[_MAX_PATH]; GetTempPath(_MAX_PATH, szTempPath); GetTempFileName(szTempPath,_T (“my_”),0,szTempfile); CFile m_tempFile(szTempfile,CFile:: modeCreate|CFile:: modeWrite); char m_char=‘a’; m_tempFile.Write(&m_char,2); m_tempFile.Close(); |
5.檔案的複製、刪除等
MFC中沒有提供直接進行這些操作的功能,因而要使用SDK。SDK中的檔案相關函數常用的有CopyFile()、CreateDirectory()、DeleteFile()、MoveFile()。它們的用法很簡單,可參考MSDN。