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