C++文件流

文件讀寫(xiě)是幾乎所有開(kāi)發(fā)語(yǔ)言中比較基礎(chǔ)和重要的應(yīng)用铸题,C++作為跨平臺(tái)語(yǔ)言,提供了以流為媒介的操作接口同仆,可以非常方便地實(shí)現(xiàn)各類文件的讀寫(xiě)倚舀。

fstream類

C++中文件讀寫(xiě)的主要接口類是fsteam類细睡,fstream類包含在頭文件<fstream>中谷羞,繼承自iostream

類似于iostreamostream溜徙、istream的關(guān)系湃缎,C++中還有ifstreamofstream類,分別實(shí)現(xiàn)文件的讀和寫(xiě)萌京,注意ifstream繼承自istream雁歌,ofstream繼承自ostream;使用方式和fstream基本一致知残,因此本文重點(diǎn)討論fstream靠瞎。

fstream對(duì)象內(nèi)部維護(hù)了一個(gè)filebuf對(duì)象,作為流緩沖區(qū)求妹,用來(lái)暫存文件從物理存儲(chǔ)設(shè)備讀取之后或?qū)懭胫暗膬?nèi)容乏盐;filebuf與物理存儲(chǔ)上的文件關(guān)聯(lián)的方式是調(diào)用fstreamopen操作;一旦filebuf與物理文件關(guān)聯(lián)之后制恍,對(duì)filebuf的任何操作等同于對(duì)物理文件的操作父能。

fstream的構(gòu)造函數(shù)有兩種形式,分別為默認(rèn)的不帶參的構(gòu)造函數(shù)净神,以及帶參數(shù)(filename何吝,openmode)的構(gòu)造函數(shù);調(diào)用帶參數(shù)的構(gòu)造函數(shù)時(shí)鹃唯,構(gòu)造的同時(shí)會(huì)關(guān)聯(lián)文件爱榕,從而不用調(diào)用open操作。

fstream();  
explicit fstream (const char* filename,
                  ios_base::openmode mode = ios_base::in | ios_base::out);

打開(kāi)/關(guān)閉文件

  • 關(guān)聯(lián)(打開(kāi))文件 -- open坡慌,open操作帶兩個(gè)輸入?yún)?shù)
    • const char* filename -- 文件名
    • ios_base::openmode mode -- 關(guān)聯(lián)模式

open操作內(nèi)部實(shí)際是調(diào)用rdbuf(一個(gè)指向內(nèi)部filebuf對(duì)象的指針)黔酥;如果fstream已經(jīng)關(guān)聯(lián)到某個(gè)文件,再次調(diào)用open將會(huì)失敽殚佟跪者;

簡(jiǎn)單說(shuō)一下openmode,6種模式熄求,可以組合使用:

模式 解釋 說(shuō)明
in input 只讀
out output 只寫(xiě)
binary binary 文件以二進(jìn)制方式操作渣玲,而非文本方式
ate at end 定位到文件結(jié)尾,寫(xiě)操作將會(huì)清空原文件
app append 寫(xiě)文件操作從文件結(jié)尾開(kāi)始抡四,追加內(nèi)容
trunc truncate 文件原有內(nèi)容將會(huì)被忽略柜蜈,即覆蓋原文件

其中仗谆,容易誤解的是ate和app指巡,它們的區(qū)別可以參考ios::app與ios::ate的區(qū)別

文件是否關(guān)聯(lián)(打開(kāi))成功淑履,可以通過(guò)is_open來(lái)判斷;

  • 關(guān)閉文件 -- close藻雪,讀寫(xiě)操作完成后秘噪,需要取消文件關(guān)聯(lián);

寫(xiě)文件

與寫(xiě)操作相關(guān)的函數(shù):

  • put
    put是向文件中寫(xiě)入字符勉耀,函數(shù)原型:ostream& put (char c);
  • write
    write是向文件中寫(xiě)入字符串指煎,函數(shù)原型:ostream& write (const char* s, streamsize n);
  • <<操作符
    <<向文件寫(xiě)內(nèi)容和像cout寫(xiě)操作相同,非常簡(jiǎn)單易用便斥;

寫(xiě)文件示例:

#include <fstream>
#include <string>

int main(int argc, char** argv) {
    std::ofstream ofs("test.txt");
    std::string new_content = "pine_apple water_melon ";
    ofs.write(new_content.c_str(), new_content.size());
    ofs << "blue_berry" << std::endl;
    ofs.put('l');
    ofs.put('e');
    ofs.put('m');
    ofs.put('o');
    ofs.put('n');

    ofs.close();
}

寫(xiě)入后的文件內(nèi)容:

pine_apple water_melon blue_berry
lemon

讀文件

  • 讀文件(針對(duì)文本文件)的一種方式是:
    • 先獲取文件長(zhǎng)度至壤,可以配合使用seekgtellg函數(shù),seekg(streamoff off, ios_base::seekdir way)可實(shí)現(xiàn)相對(duì)于某位置枢纠,去移動(dòng)下一個(gè)字符指針的偏移位置像街,最常用的是seekg(0, ios_base::end)seekg(0, ios_base::beg),從而將指針位置移動(dòng)到文件結(jié)尾或開(kāi)始晋渺;tellg()返回當(dāng)前字符在文件流中的位置镰绎;可以先將指針移動(dòng)到結(jié)尾,然后獲取結(jié)尾字符的位置作為文件長(zhǎng)度木西,最后再將指針移動(dòng)回開(kāi)始的位置畴栖;
    • 將文件內(nèi)容全部或部分讀取,或者循環(huán)遍歷讀取字符或字符串八千;讀文件可調(diào)用read操作吗讶,read可返回任意個(gè)數(shù)的字符到字符數(shù)組中,所以需要輸入2個(gè)參數(shù)恋捆,char* sstreamsize n;

附帶一個(gè)讀文件的demo實(shí)例(來(lái)自http://www.cplusplus.com/reference/istream/istream/read/

// read a file into memory
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream

int main () {

  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    char * buffer = new char [length];

    std::cout << "Reading " << length << " characters... ";
    // read data as a block:
    is.read (buffer,length);

    if (is)
      std::cout << "all characters read successfully.";
    else
      std::cout << "error: only " << is.gcount() << " could be read";
    is.close();

    // ...buffer contains the entire file...

    delete[] buffer;
  }
  return 0;
}

讀文件除了采用read函數(shù)以外照皆,還有多種方式,比如getline函數(shù)鸠信,可以獲取每一行的內(nèi)容纵寝,默認(rèn)的分隔符是'\n',也可以通過(guò)參數(shù)設(shè)置分隔符星立;
istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );

  • 另一種讀文件方式 -- 迭代器來(lái)讀取文件:
    istream_iterator可以從輸入流中連續(xù)讀取元素爽茴,一般以空格作為分割,可以像普通迭代器一樣遍歷文本文件绰垂,也可以直接將字符串讀入vector容器中室奏。

代碼示例:

#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
 
int main()
{
    std::ifstream ifs("test.txt");
    std::istream_iterator<std::string> iit(ifs);
    std::istream_iterator<std::string> eos;
    std::vector<std::string> vec(iit, eos);
    std::cout << "vec size: " << vec.size() << std::endl;
    for(size_t i = 0; i < vec.size(); ++i) {
        std::cout << vec[i] << " ";
    }
    std::cout << std::endl;
    ifs.close();
   
    return 0;
}

二進(jìn)制文件讀寫(xiě)

二進(jìn)制文件的讀寫(xiě)與文本文件讀寫(xiě)本質(zhì)上是一致的,只不過(guò)在關(guān)聯(lián)文件的時(shí)候劲装,應(yīng)當(dāng)組合std::ios::binary模式胧沫;以下給出一個(gè)簡(jiǎn)單的示例:

  • 向一個(gè)二進(jìn)制文件寫(xiě)入0~9共9個(gè)數(shù)字:
#include <fstream>
#include <string>

int main(int argc, char** argv) {
    std::ofstream ofs("bin_test", std::ios::out | std::ios::binary);
    
    for(size_t i = 0; i < 10; ++i) {
        ofs.put(char(i));
    }

    ofs.close();
}
  • 讀入剛才寫(xiě)的二進(jìn)制文件
#include <fstream>
#include <string>
#include <iostream>

int main(int argc, char** argv) {
    std::ifstream ifs("bin_test", std::ios::in | std::ios::binary);
    
    // get file content lenth
    ifs.seekg(0, ifs.end);
    int len = ifs.tellg();
    ifs.seekg(0, ifs.beg);

    // read data
    char* data = new char[len];
    ifs.read(data, 10);
    for(size_t i = 0; i < len; ++i) {
        std::cout << (int)(data[i]) << std::endl;
    }

    ifs.close();
    delete[] data;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昌简,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绒怨,更是在濱河造成了極大的恐慌纯赎,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件南蹂,死亡現(xiàn)場(chǎng)離奇詭異犬金,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)六剥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門晚顷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人疗疟,你說(shuō)我怎么就攤上這事该默。” “怎么了策彤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵栓袖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锅锨,道長(zhǎng)叽赊,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任必搞,我火速辦了婚禮必指,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恕洲。我一直安慰自己塔橡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布霜第。 她就那樣靜靜地躺著葛家,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泌类。 梳的紋絲不亂的頭發(fā)上癞谒,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音刃榨,去河邊找鬼弹砚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛枢希,可吹牛的內(nèi)容都是我干的桌吃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼苞轿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼茅诱!你這毒婦竟也來(lái)了逗物?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瑟俭,失蹤者是張志新(化名)和其女友劉穎翎卓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體尔当,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡莲祸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年蹂安,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了椭迎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡田盈,死狀恐怖畜号,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情允瞧,我是刑警寧澤简软,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站述暂,受9級(jí)特大地震影響痹升,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畦韭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一疼蛾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧艺配,春花似錦察郁、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至赠法,卻和暖如春麦轰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背砖织。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工款侵, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人镶苞。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓喳坠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親茂蚓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壕鹉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • C/C++輸入輸出流總結(jié) 前兩天寫(xiě)C++實(shí)習(xí)作業(yè)剃幌,突然發(fā)現(xiàn)I/O是那么的陌生,打了好長(zhǎng)時(shí)間的文件都沒(méi)有打開(kāi)晾浴,今天終...
    LuckTime閱讀 1,738評(píng)論 0 6
  • [轉(zhuǎn)]C/C++ 文件讀寫(xiě)操作總結(jié) 在編程的過(guò)程中负乡,文件的操作是一個(gè)經(jīng)常用到的問(wèn)題,在C++Builder中脊凰,可以...
    天之道天知道閱讀 5,200評(píng)論 0 7
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,523評(píng)論 1 51
  • ??在c++中引入了stream抖棘,一開(kāi)始接觸這個(gè)的時(shí)候感覺(jué)無(wú)法正確的理解stream的用法,在寫(xiě)項(xiàng)目的時(shí)候要用到讀...
    UnderwoodY閱讀 12,264評(píng)論 0 5
  • 1狸涌、 我小的時(shí)候特別怕阿爸切省,幾乎連吃飯都不敢和他同一張桌子。我只盛一丁點(diǎn)兒飯帕胆,大概就是小貓小狗吃的朝捆。我捏緊筷子,手...
    胡識(shí)閱讀 757評(píng)論 9 13