【C++】fstream文件操作


C語言使用FILE對文件進行操作,常用到的函數有fopen()freopen()fread()fwrite()fclose()等,分別用來打開文件、讀寫文件、關閉文件。

C++可以使用fstream文件流對文件進行操作,使用時需要引入頭文件:#include <fstream>。可以使用ifstream、ofstream、fstream文件流對文件進行輸入(讀)、輸出(寫)、輸入輸出(讀寫)操作。Ifstream支持>>操作,ofstream支持<<操作,fstream同時支持>>和<<操作。

本文簡單介紹C++文件流的操作:

目錄

       一、 打開、關閉文件

       二、 讀寫文件

       三、 定位文件指針、獲取文件大小

   四、 示例代碼

 

一、打開、關閉文件

  1. 打開文件 fstream可以在聲明流對象時傳入文件名打開文件,也可以使用open()函數打開文件。
  2. 關閉文件 文件打開后必須關閉,fstream提供close()函數關閉文件。

  打開文件

  • 使用構造函數聲明對象時打開文件,示例:
fstream file(filename, ios::in | ios::out);
  • 使用open()函數打開文件,函數原型:
void open(const char* filename,int mode,int access);  // filename—文件名;mode—打開文件的模式;access—文件屬性

  如果只傳入文件名,系統會自動根據文件類型選擇默認的打開模式。

  打開文件模式mode及文件屬性access取值如下:

mode 打開文件模式 說明

access

文件屬性 說明
ios::app 以追加的方式打開文件 0 普通文件,打開訪問
ios::ate 文件打開后定位到文件尾,ios::app包含此屬性
ios::binary 以二進制方式打開文件,默認是文本文件 1 只讀文件
ios::in 以輸入方式打開,讀出文件內容
ios::out 以輸出方式打開,寫入文件內容 2 隱含文件
ios::nocreate 以不創建文件的方式打開文件,如果文件不存在,打開失敗
ios::noreplace 以不覆蓋的方式打開文件,如果文件存在,打開失敗 4 系統文件
ios::trunc 如果文件存在,清空文件內容

  說明:

  • 模式和屬性可以單獨使用給,也可以混合使用。混合使用時,用邏輯連接符或 |連接。
  • ios::out模式默認會清空,即iios::out|ios::trunc和ios::out打開文件時都會清空文件。如果不想清空文件,那么設置讀寫模式為ios::out|ios::app,以這種模式打開文件后,數據會以追加的方式寫入到文件。

二、 讀寫文件

       fstream提供的讀寫操作有:<<>>read()write()put()get()getline()。根據文件類型可分為文本文件和二進制文件,根據讀寫方式可分為逐行讀寫和整塊讀寫。通常,文本文件使用逐行讀寫的方式,二進制文件使用整塊讀寫的方式。

       1. 文本文件讀寫

    文本文件通常使用逐行讀寫的方式。逐行讀取文本文件時可以使用getline()函數。系統庫和fstream都提供了同名的getline()函數,不同點在於fstream文件流提供的getline()函數是C語言格式的,而系統庫提供的getline()函數是C++格式的,如下:

fstream提供的getline()函數

系統庫提供的getline()函數

ifstream in(“test.txt”);

char temp[1024]’

while(!in.eof()) {

    in.getline(temp,1024);

}

ifstream in(text.txt);

std::string strline;

while(!in.eof()) {

    getline(in,strline);

}

    逐行寫入文本文件可以使用操作符<<。

       2. 二進制文件的讀寫

              二進制文件通常整塊讀取或寫入,當然也可以讀寫單個字符,用到的函數包括:put()、get()、read()、write()

              通常使用write()、put()函數寫入二進制文件。使用read()、get()讀取二進制文件。

  • 讀寫數據塊

              使用read()write()函數讀寫數據塊,原型如下:

    istream& read(char* buffer,int count);
    ofstream& write(char* buffer,int count);  //從buf指向的緩存向文件寫入count個字符。

              需要注意的是:read()函數從文件中讀取count個字符,讀取到buffer指向的緩存中,如果還未讀入num個字符就到了文件尾,可以用成員函數gcount()獲取實際讀取的字符數。

  • 讀寫單個字符

              通常使用get()、put()函數讀寫單個字符

              put()函數向文件寫入一個字符,原型為ofstream& put(char ch);

              get()函數從文件讀取一個字符,有三種重載形式:

      ①     ifstream& get(char& ch);   從流中讀取一個字符,如果到文件尾,返回空字符。

      ②     int get();   從流中返回一個字符,如果到達文件尾,返回EOF,

      ③     ifstream& get(char* buf,int count,char delim=”\n;   把字符讀入buf指向的緩存中,知道讀入了count個字符或者遇到delim指定的字符。

三、 定位文件指針、獲取文件大小

       C++的文件定位分為讀位置和寫位置的定位,對應的成員函數分別為seekg()和seekp()。

  seekg()函數設置讀位置,seekp()設置寫位置。函數原型如下:

         istream& seekg(streamoff offset,seek_dir origin);
         ofstream& seekp(streamoff offset,seek_dir origin);

           offset表示偏移量,seek_dir表示移動的基准位置,取值如下:

                  ios::beg          文件開頭

                  ios::cur           文件當前位置

                  ios::end          文件結尾

       示例:

    inFile.seekg(12,ios::beg);  // 把文件讀指針從開始位置向后移動12個字節
    outFile.seekp(12,ios::cur);  // 把文件寫指針從當前位置向后移動12個字節

  獲取文件大小可以使用seekg()tellg()或者seekp()tellp()函數結合使用的方式獲取文件大小。

       示例:

    inFile.seekg(0,ios::end);  // 讀文件指針移動到文件末尾
    streampos ipos = inFile.tellg();  //返回當前指針的位置,也就是文件的大小,單位是字節

四、 示例代碼

    //讀寫txt文件
    std::string in_read_txt = "in_read.txt";
    std::ifstream file_in_read_txt(in_read_txt);  // 讀取文件
    // 文本文件逐行讀取數據
    if(!file_in_read_txt.is_open())  // 判斷文件是否打開
    {
        std::string sErrmsg = "Open File FAIL";
        throw sErrmsg;
    }

    std::string strline;
    std::vector<std::string> vecLine;

    while (getline(file_in_read_txt,strline)) {  // 逐行獲取txt內容
        std::cout << strline << std::endl;
        vecLine.push_back(strline);
    }

    file_in_read_txt.close();

    // 文本文件逐行寫入
    std::string out_write_txt = "out_write.txt";
    std::ofstream file_out_write_txt(out_write_txt,std::ios::trunc);  // 寫入txt文件
    if(!file_out_write_txt.is_open())
    {
        std::string sErrmsg = "Open File FAIL";
        throw sErrmsg;
    }
    for(std::string& line : vecLine)
    {
        file_out_write_txt << line << std::endl;  //逐行寫入文件
    }
    file_out_write_txt.close();


    std::string in_read_bin = "in_read.bin";
    std::string out_write_bin = "out_write.bin";

    std::ifstream file_in_read_bin(in_read_bin,std::ios::binary);  // 以二進制方式讀取文件
    std::ofstream file_out_write_bin(out_write_bin,std::ios::binary);  // 以二進制方式寫入文件

    // 二進制文件獲取數據
    if(!file_in_read_bin.is_open())
    {
        std::string sErrmsg = "Open File FAIL";
        throw sErrmsg;
    }
    uchar binData[2048] = {0};
    file_in_read_bin.read((char*)binData,sizeof(binData));
    int iDataSize = file_in_read_bin.gcount();
    printf("Read Data Size = %d\n",iDataSize);
    for(int i=0;i<iDataSize;i++)
    {
        printf("0x%04x,0x%02x\n",i,binData[i]);
    }

    //使用get()函數獲取文件內容
    //  char chTemp;

    // 第一種用法
    //    while (file_in_read_bin.get(chTemp)) {
    //        printf("0x%02x\n",(uchar)chTemp);
    //    }

    // 第二種用法
    //    for(int i=0;i<1372;i++)
    //    {
    //        chTemp = file_in_read_bin.get();
    //        printf("0x%02x\n",(uchar)chTemp);
    //    }

    // 第三種用法
    //    file_in_read_bin.get((char*)binData,sizeof(binData));
    //    for(int i=0;i<sizeof(binData);i++)
    //    {
    //        printf("0x%04x,0x%02x\n",i,binData[i]);
    //    }

    file_in_read_bin.close();

    // 寫入bin文件
    if(!file_out_write_bin.is_open())
    {
        std::string sErrmsg = "Open File FAIL";
        throw sErrmsg;
    }
    file_out_write_bin.write((char*)binData,iDataSize);
    file_out_write_bin.close();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM