如何用 C++ 讀寫文件
在 C++ 中,對文件的讀寫可以通過使用輸入輸出流與流運算符 >> 和 << 來進(jìn)行。當(dāng)讀寫文件的時候,這些運算符被應(yīng)用于代表硬盤驅(qū)動器上文件類的實例上。這種基于流的方法有個巨大的優(yōu)勢:從  C++  的角度,無論你要讀取或?qū)懭氲膬?nèi)容是文件、數(shù)據(jù)庫、控制臺,亦或是你通過網(wǎng)絡(luò)連接的另外一臺電腦,這都無關(guān)緊要。因此,知道如何使用流運算符來寫入文件能夠被轉(zhuǎn)用到其他領(lǐng)域。
輸入輸出流類
C++ 標(biāo)準(zhǔn)庫提供了 ios_base 類。該類作為所有 I/O 流的基類,例如 basic_ofstream 和 basic_ifstream。本例將使用讀/寫字符的專用類型 ifstream 和 ofstream。
ofstream:輸出文件流,并且其能通過插入運算符<<來實現(xiàn)。ifstream:輸入文件流,并且其能通過提取運算符>>來實現(xiàn)。
該兩種類型都是在頭文件 <fstream> 中所定義。
從 ios_base 繼承的類在寫入時可被視為數(shù)據(jù)接收器,在從其讀取時可被視為數(shù)據(jù)源,與數(shù)據(jù)本身完全分離。這種面向?qū)ο蟮姆椒ㄊ?nbsp;關(guān)注點分離 和 依賴注入 等概念易于實現(xiàn)。
一個簡單的例子
本例程是非常簡單:實例化了一個 ofstream 來寫入,和實例化一個 ifstream 來讀取。
#include <iostream> // cout, cin, cerr etc...#include <fstream> // ifstream, ofstream#include <string>int main(){std::string sFilename = "MyFile.txt";/******************************************* ** WRITING ** *******************************************/std::ofstream fileSink(sFilename); // Creates an output file streamif (!fileSink) {std::cerr << "Canot open " << sFilename << std::endl;exit(-1);}/* std::endl will automatically append the correct EOL */fileSink << "Hello Open Source World!" << std::endl;/******************************************* ** READING ** *******************************************/std::ifstream fileSource(sFilename); // Creates an input file streamif (!fileSource) {std::cerr << "Canot open " << sFilename << std::endl;exit(-1);}else {// Intermediate bufferstd::string buffer;// By default, the >> operator reads word by workd (till whitespace)while (fileSource >> buffer){std::cout << buffer << std::endl;}}exit(0);}
該代碼可以在 GitHub 上查看。當(dāng)你編譯并且執(zhí)行它時,你應(yīng)該能獲得以下輸出:
Console screenshot
這是個簡化的、適合初學(xué)者的例子。如果你想去使用該代碼在你自己的應(yīng)用中,請注意以下幾點:
- 文件流在程序結(jié)束的時候自動關(guān)閉。如果你想繼續(xù)執(zhí)行,那么應(yīng)該通過調(diào)用 
close()方法手動關(guān)閉。 - 這些文件流類繼承自 basic_ios(在多個層次上),并且重載了 
!運算符。這使你可以進(jìn)行簡單的檢查是否可以訪問該流。在 cppreference.com 上,你可以找到該檢查何時會(或不會)成功的概述,并且可以進(jìn)一步實現(xiàn)錯誤處理。 - 默認(rèn)情況下,
ifstream停在空白處并跳過它。要逐行讀取直到到達(dá) EOF ,請使用getline(...)方法。 - 為了讀寫二進(jìn)制文件,請將 
std::ios::binary標(biāo)志傳遞給構(gòu)造函數(shù):這樣可以防止 EOL 字符附加到每一行。 
從系統(tǒng)角度進(jìn)行寫入
寫入文件時,數(shù)據(jù)將寫入系統(tǒng)的內(nèi)存寫入緩沖區(qū)中。當(dāng)系統(tǒng)收到系統(tǒng)調(diào)用 sync 時,此緩沖區(qū)的內(nèi)容將被寫入硬盤。這也是你在不告知系統(tǒng)的情況下,不要卸下 U 盤的原因。通常,守護(hù)進(jìn)程會定期調(diào)用 sync。為了安全起見,也可以手動調(diào)用 sync():
#include <unistd.h> // needs to be includedsync();
總結(jié)
在 C++ 中讀寫文件并不那么復(fù)雜。更何況,如果你知道如何處理輸入輸出流,(原則上)那么你也知道如何處理任何類型的輸入輸出設(shè)備。對于各種輸入輸出設(shè)備的庫能讓你更容易地使用流運算符。這就是為什么知道輸入輸出流的流程會對你有所助益的原因。
















 
 
 




 
 
 
 