1. 程式人生 > >CFile、CStdioFile、FILE和其他檔案操作(轉+總結)

CFile、CStdioFile、FILE和其他檔案操作(轉+總結)

CFile、CStdioFile、FILE和其他檔案操作(轉+總結)  

2010-04-10 20:36:33|  分類: VC++|舉報|字號 訂閱

           下載LOFTER 我的照片書  |    

CFile


//建立/開啟檔案
CFile file;
file.Open(_T("test.txt"),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite);

檔案開啟模式可組合使用,用“|”隔開,常用的有以下幾種:
CFile::modeCreate:以新建方式開啟,如果檔案不存在,新建;如果檔案已存在,把該檔案長度置零,即清除檔案原有內容。
CFile::modeNoTruncate:以追加方式開啟,如果檔案存在,開啟並且不將檔案長度置零,如果檔案不存在,會丟擲異常。一般與CFile::modeCreate一起使用,則檔案不存在時,新建一個檔案;存在就進行追加操作。
CFile::modeReadWrite:以讀寫方式開啟檔案。
CFile::modeRead:只讀。
CFile::modeWrite:只寫。

//寫入資料
CString strValue = "Hello World!";
file.Write(strValue,strValue.GetLength());

//追加資料
file.SeekToEnd(); //將指標移至檔案末尾進行追加
file.Write(strValue,strValue.GetLength());

//關閉檔案
file.Close();

CStdioFile
CStdioFile是CFile的派生類,對檔案進行流式操作,對於文字檔案的讀寫很有用處,可按行讀取寫入。

//寫入資料
CString strValue = "Hello World!";
file.WriteString(strValue);

//讀取資料
CString strRead;
file.ReadString(strRead);

當檔案存在多行資料需要逐行讀取時,可用函式BOOL CStdioFile::ReadString(CString& rString),當遇到"\n "時讀取截斷,如果檔案未讀完,返回true,否則返回false。

//逐行讀取檔案內容,存入strRead
while(file.ReadString(strRead))
{
 ...;
}

各種關於檔案的操作在程式設計中是十分常見,如果能對其各種操作都瞭如指掌,就可以根據實際情況找到最佳的解決方案,從而在較短的時間內編寫出高效的程式碼,因而熟練的掌握檔案操作是十分重要的。本文將對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_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 );
  }
  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(); (Forces any data remaining in the file buffer to be written to the file)
  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<<  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();
 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。

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
則(1)GetPathName();取檔名全稱,包括完整路徑。取回C:\WINDOWS\TEST.EXE
(2)GetFileTitle();取檔案全名:TEST.EXE
(3)GetFileName();取回TEST
(4)GetFileExt();取副檔名EXE

[2]開啟檔案
CFile file("C:\HELLO.TXT",CFile::modeRead);//只讀方式開啟
//CFile::modeRead可改為 CFile::modeWrite(只寫),
//CFile::modeReadWrite(讀寫),CFile::modeCreate(新建)
例子:
{
CFile file;
file.Open("C:\HELLO.TXT",CFile::modeCreate|Cfile::modeWrite);
.
.
.
}

[3]移動檔案指標
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();


本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/paodan/archive/2009/08/20/4466259.aspx

 

CFile Read函式與CStdioFile的ReadString函式比較,Read 函式可以讀取指定大小的字串,ReadString可以讀取到換行符前的所有字串,而File函式的fgetc()也可以讀取,但一次只能得到一個位元組

 

FILE ,其與CFILE 有點相似.示例如下

  char datain[101];
  FILE *fp_sys;
  //開啟資料檔案
  fp_sys = fopen("要開啟的檔名", "rb");//第二個引數為開啟方法,r代表讀,b代表二進位制方式

  if(fp_sys == NULL) {
   AfxMessageBox("無法開啟檔案");
   return FALSE;
  }
  //讀取資料檔案
  fread(datain, sizeof(unsigned char ), 42, fp_sys);//引數說明:第一個是接收的變數,第二個是型別的記憶體大小,第三個是字數的數量,第四個是讀的檔案

//寫出資料到檔案

fwrite(output_data, sizeof(unsigned char ), 40, fp_out););//引數說明:第一個是要寫出的變數,第二個是型別的記憶體大小,第三個是字數的數量,第四個是寫的檔案

 

CStdioFile類學習筆記

      CStdioFile類的宣告儲存再afx.h標頭檔案中。
CStdioFile類繼承自 CFile類, CStdioFile物件表示一個用執行時的函式fopen開啟的c執行時的流式檔案。流式檔案是被緩衝的,而且可以以文字方式(預設)或者 二進位制方式開啟。
CStdioFile類不支援 CFile類中的Duplicate、LockRange、UnlockRange函式,如果你使用了,會得到CNotSupportedException類的錯誤。
CStringFile類預設的是按照Text模式操作檔案。 CFile 類預設的是按照 二進位制模式操作檔案。
這裡大致說明一下 二進位制模式和Text模式的區別。
二進位制模式:對於一行的結尾我們必須輸入”\r\n”,才能表示回車換行的效果。
Text模式:”\r”回車的工作是自動完成的,我們只需要寫入”\n”即可。所以我們再使用文字模式時要主要,當我們從外部讀入檔案時,”\r\n”會被翻譯成”\n”,寫入檔案時,我們對於回車換行只需提供”\n”,即可,”\r\n”會被寫入到檔案中。
m_pStream成員變數:
      開啟檔案的指標。
 
建構函式:
CStdioFile();
CStdioFile(FILE *pOpenStream);
CStdioFile(LPCTSTR lpFileName, UINT nOpenFlags);
throw(CFileException);
FILE *pOpenStream:指的是c執行函式fopen呼叫後返回的檔案指標。
LPCTSTR lpFileName:指的是被開啟的檔案(絕對地址或相對地址)
UINT nOpenFlags:指的是 CFile類中所描述的開啟檔案的方式。
 
virtual LPTSTR ReadString(LPTSTR lpsz, UINT nMax);
throw(CFileException);
如果使用該函式讀取文字檔案,當遇到”\r\n”,停止讀取,並去掉”\r”,保留”\n”,並在字串尾部增加”\0”,nMax的長度包含有”\0”字元,
實際的分析如下:
如果nMax <= 字元數,讀取(nMax-1)個字元+0x00;
如果nMax = 字元數 + 1,讀取nMax個字元+0x00;
如果nMax > 字元數,讀取nMax個字元+0x0A(”\n”) + 0x00;
如果檔案有多行,則當檔案沒有讀完時,返回NOT NULL,讀到檔案尾,返回NULL。
 
BOOL ReadString(CString& rString);
throw(CFileException);
讀取一行文字到rString中,遇到回車換行符停止讀取,回車和換行符均不讀到rString中,尾部也不新增”0x00”。
如果檔案有多行,則當檔案沒有讀完時,返回TRUE,讀到檔案尾,返回FALSE。
 
virtual void WriteString(LPTSTR lpsz);
throw(CFileException);
將緩衝區中的資料寫入到與 CStdioFile物件相關聯的檔案中,不支援CString型別資料寫入,結束的”\0”不被寫入到檔案中,lpsz緩衝區中的所有換行符被替換為回車換行符即”\n”轉換為”\r\n”。