C++(十六)文件IO操作(讀寫)


C++的文件IO(Input,Output)操作就是指對文件進行讀寫(輸入與輸出)的操作。輸入就是從磁盤上的文件中讀取內容到內存中。輸出就是將內存中的數據內容輸出或者說寫入到磁盤的文件中。

一、文件的類型

文件的類型分爲文本文件二進制文件,文本文件又稱爲ASCII文件,它的每個字節存放一個ASCII碼,代表一個字符。二進制文件則是把內存中的數據,按照其在內存中的存儲形式原樣寫在磁盤上存放。
我們經常用文本形式存儲數據,缺點則是佔用存儲空間較多。用二進制形式輸出數據,節省了轉化時間和存儲空間,但不能直接以字符的形式輸出,所以看不懂。一般根據自己的需要選擇使用文本文件還是二進制文件存儲。

#include <fstream>
using namespace std;

int main()
{
    short var = 20000;
    ofstream fs;
    fs.open("d:\\123.txt");
    fs << var;                                   // 一般使用 << 寫文本文件
    fs.close();

    ofstream fs2;
    fs2.open("d:\\456.txt");
    fs2.write((const char*)&var, sizeof(short));  // 使用 write函數寫二進制文件
    fs2.close();

    short value = 0;
    ifstream fi;
    fi.open("d:\\456.txt");
    fi.read((char*)&value, sizeof(short));       // 讀取二進制文件類型
    return 0;
}

文件的寫操作:
寫文本類型/ASCII碼類型的可見字符串:<<、put(put 只能寫單個字符到文件)
①、<<重寫函數:http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/

write() 函數的第一個參數是 char* 類型(也就是一個地址),char * 不一定是字符串,也可能是二進制數據。第二個參數就是要一個長度,要從多長的一塊內存數據寫到文件中。

文件的讀操作:
①、讀文本類型/ASCII碼類型的文件:>>、get、getline
>>支持的類型詳見:http://www.cplusplus.com/referen … eam/operator%3E%3E/
istream::get 詳見:http://www.cplusplus.com/reference/istream/istream/get/
getline() 函數,該函數是從文件中讀取一行數據,直到有換行符 \n,或者達到 getline 的緩衝區大小,或者讀到文件末尾。
istream::getline 詳見:http://www.cplusplus.com/reference/istream/istream/getline/

②、讀取二進制文件類型:read
read() 函數:http://www.cplusplus.com/reference/istream/istream/read/
從指定的文件中讀取數據,讀取的數據可以是文本類型的也可以是二進制類型的,把讀取到的內容放在第一個參數指針指向的內存中,具體讀取的字節數就是靠第二個參數指定。

二、文件操作類詳情:

C++文件流:
fstream(輸入輸出文件流):支持文件的輸入與輸出操作;
ifstream(輸入文件流):支持從文件中輸入操作;
ofstream(輸出文件流):支持向文件寫入的操作;

實際上這幾個類都是C++標準模板庫STL中提供給我們的,現成的,寫好的文件流操作類,我們可以直接拿過來用!
C++本身兼容C語言,所以C語言中的文件讀寫函數仍然支持,比如:fopen、fread、fwrite、fclose 等等。

文件的打開操作:構造函數與open函數
ofstream fs("z:\\123.txt");
fs.open("z:\\123.txt");

這兩種操作都是可以的。當前我們這裏只使用了第1個參數,即:傳入了文件的路徑。實際上open函數有多個參數,第2個參數,表示打開文件的方式,

詳情如下:
ios::in:爲輸入 () 而打開文件,文件不存在則創建
ios::out:爲輸出 () 而打開文件,文件不存在則創建,若文件已存在則清空原內容
ios::ate:初始位置:文件尾,常和in、out聯合使用
ios::app:文件末尾追加內容
ios::trunc:如果文件已存在則先刪除該文件
ios::nocreate:文件不存在時產生錯誤,常和in或app聯合使用
ios::noreplace:文件存在時產生錯誤,常和out聯合使用
ios::binary二進制方式

ofstream、ifstream、fstream 的open函數或者構造函數都有默認的打開文件的方式,如果不傳第2個參數,那麼就用默認的,其值如下:

ofstream fs1("123.txt", ios::out);             //(創建文件)寫入內容
ifstream fs2("123.txt", ios::in);              // 讀取內容
fstream fs3("123.txt", ios::in|ios::out);      // 以讀寫方式打開文件


ifstream f("d:\\12.txt", ios::nocreate);     //默認ios::in 的方式打開文件,文件不存在時操作失敗
fstream f("d:\\12.dat", ios::in|ios::out|ios::binary); //以讀、寫方式打開二進制文件
文件打開判斷、文件保護

文件保護方式
filebuf::openprot;   //默認的兼容共享方式
filebuf::sh_none;    //獨佔,不共享
filebuf::sh_read;    //讀共享
filebuf::sh_write;   //寫共享

如何判斷文件是否打開成功了呢?open函數的返回值是 void 類型,以下方法都可以:
①、直接 if 判斷 fs 對象;
②、用 is_open 方法判斷;
③、用 good 方法判斷;沒有發生任何錯誤的時候返回true
④、用 fail 方法判斷;判斷最後一次讀取數據的時候是否遇到了類型不配的情況,若是返回true(如果遇到了EOF,該方法也返回true)

小示例:

#include "stdafx.h"
#include <fstream>
#include <iostream>
using namespace std;



int main()
{
	ifstream fii("C:\\Users\\xxx\\Desktop\\111.txt");
	if(!fii)
	{
		cout << "file open error!" << endl;
		return -1;
	};

	
	ifstream fiii("C:\\Users\\xxx\\Desktop\\111.txt");
	if (!fiii.is_open())
	{
		cout << "file open error!" << endl;
		return -1;
	}

}
讀取文件的三種方式
#include <iostream>
#include <fstream>
#include <cassert>
#include <string>


// 逐行讀入
void readTxt(string file)
{
    ifstream infile; 
    infile.open(file.data());   //將文件流對象與文件連接起來 或者infile.open(./xxx.txt)
    assert(infile.is_open());   //若失敗,則輸出錯誤消息,並終止程序運行 

    string s;
    while(getline(infile,s))
    {
        cout<<s<<endl;
    }
    infile.close();             //關閉文件輸入流 
}


//逐個字符讀入(忽略空格與回車)
void readTxt(string file)
{
    ifstream infile; 
    infile.open(file.data());   //將文件流對象與文件連接起來 
    assert(infile.is_open());   //若失敗,則輸出錯誤消息,並終止程序運行 

    char c;
    while (!infile.eof())
    {
        infile >> c;
        cout<<c<<endl;

    }
    infile.close();             //關閉文件輸入流 
}

//逐個字符讀入(包括空格與回車)
void readTxt(string file)
{
    ifstream infile; 
    infile.open(file.data());   //將文件流對象與文件連接起來 
    assert(infile.is_open());   //若失敗,則輸出錯誤消息,並終止程序運行 

    char c;
    infile >> noskipws;
    while (!infile.eof())       //達到文件末尾
    {
        infile>>c;
        cout<<c<<endl;

    }
    infile.close();             //關閉文件輸入流 
}

eof() 方法用於判斷最後一次讀取數據的時候是否遇到EOF,即到達文件末尾,若是則返回true。

三、文件指針

在讀寫文件的時候,每讀取或者寫入一個字節,磁盤中的文件指針就會向後移動一個字節。可以通過控制指針的位置,以便在我們需要的位置進行讀寫文件。

  • 文件流提供以下成員函數來讀取或配置文件指針:
    tellg() 返回讀取文件指針的當前位置
    tellp() 返回寫入文件指針的當前位置
    seekg(指針偏移量) 將讀取文件指針移到指定位置
    seekg(指針偏移量,參照位置) 將讀取文件指針移到指定位置
    seekp(指針偏移量) 將寫入文件指針移到指定位置
    seekp(指針偏移量,參照位置) 將寫入文件指針移到指定位置

備註:以上函數中的最後一個字母:其中,g代表get,表示讀取;p代表put,表示寫入
另外,函數參數中的“文件中的位置”和“指針偏移量”爲 long整型,以字節爲單位。“參照位置”是一個有以下值的枚舉:
ios::beg 文件開頭計算偏移量
ios::cur 文件當前位置計算偏移量
ios::end 文件結尾計算偏移量
其中,函數seekg(指針偏移量) 和 seekp(指針偏移量),默認從文件開頭計算偏移量。

3、使用文件指針獲取文件大小:
原理:文件結尾的位置,就代表從文件開始的位置到結尾的字節數,即文件的大小!

https://blog.csdn.net/seadplus/article/details/7802346

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章