2012-09-11 51 views
14

對於在C++中執行文件IO,我們使用ofstream,ifstream和fstream類。C++文件流打開模式歧義

  • ofstream的:Stream類對文件
  • ifstream的寫:Stream類從文件
  • fstream的閱讀:Stream類來讀取和寫入從/到文件

的將文件與流對象相關聯的過程稱爲「打開文件」。 打開文件時,我們可以指定打開文件的模式。 我的查詢與ios::outios:in模式相關。

當我創建一個ofstream對象,並打開該文件ios::in模式,我能夠 寫入該文件,但只有當它已經建立(與ios::out模式文件,如果它不存在也創建)。
但是當我創建ifstream對象並用ios::out模式打開文件時,我能夠從文件中讀取。

我的問題是爲什麼這些模式(ios::in/ios::out)由語言提供的當流(ifstream/ofstream)的種類本身指定哪個類型的操作(輸入/輸出)的正在執行?

而且爲什麼這個曖昧的用法(ofstreamios::inifstreamios::out)的作品在一種情況下,在另一個失敗(雖然只有當文件尚不存在)?

回答

11

ofstream的,ifstreamfstream類的下屬filebuf,其中一個可以通過流的rdbuf()成員函數得到高水平的接口。

根據標準當您打開ofstream某些模式mode時,它將打開下劃線流緩衝區,與mode | ios_base::out一樣。類似ifstream使用mode | ios_base::infstreammode參數逐字傳遞給下劃線流緩衝區。

什麼上面意味着下面的代碼打開完全相同的開旗的文件是:

fstream f("a.txt", ios_base::in | ios_base::out); 
ifstream g("a.txt", ios_base::out); 
ofstream h("a.txt", ios_base::in); 

這些行,你可以做後正好與f.rdbuf()g.rdbuf()h.rdbuf(),所有的同樣的事情第三幕,如果你打開了C呼叫fopen("a.txt", "r+"),它給你的讀/寫訪問的文件,不會截斷該文件,如果文件不存在失敗。

那麼,爲什麼我們有三個不同的類?正如我已經說過的,這些是高級別的類,它通過較低級別的流緩衝區提供高級接口。這個想法是,ifstream具有成員函數輸入(如read()),ofstream具有成員函數輸出(如write()),而fstream同時具備。例如,你可以這樣做:

g.write("abc", 3); // error: g does not have a write function 

但這個工程,因爲雖然gifstream,我們曾與ios_base::out打開一看:

g.rdbuf()->sputn("abc", 3); // we still have write access 
0

因爲模式不限於輸入/輸出。的ifstream構造函數,例如,看起來像:

explicit ifstream (const char * filename, ios_base::openmode mode = ios_base::in); 

注意的默認值是ios_base::in,這樣你就不必自己指定。然而,mode設置流標誌它們限於in/out,但包括:

  • app(附加)設置到每個輸出操作前的數據流的結束的流的位置指示器。
  • ate(在結束時)將流的位置指示符設置爲打開時的流尾。
  • binary(二進制)將流視爲二進制而不是文本。
  • in(輸入)允許在流上進行輸入操作。
  • out(輸出)允許輸出流上的操作。
  • trunc(截斷)任何當前內容都會被丟棄,假設打開時長度爲零。