C++文件流:
stl中對文件讀寫的函數在頭文件fstream中定義,它的基本對象模型如下:
其中包含三個對象ifstrea、ofstream和fstream,分別對文件提供只讀、只寫、讀寫功能,從其對象繼承關係也可以看出這一點。
//創建一個文本文件並寫入信息
//同向屏幕上輸出信息一樣將信息輸出至文件
#include<iomanip.h>
#include<fstream.h>
void
main()
{
ofstream f1(
"d:\\me.txt"
);
//打開文件用於寫,若文件不存在就創建它
if
(!f1)
return
;
//打開文件失敗則結束運行
f1<<setw(20)<<
"姓名:"
<<
"東方"
<<endl;
//使用插入運算符寫文件內容
f1<<setw(20)<<
"家庭地址:"
<<
"河南鄭州"
<<endl;
f1.close();
//關閉文件
}
運行後打開文件d:\me.txt,其內容如下:
姓名:東方
家庭地址:河南鄭州
文件操作:
打開文件
文件名
注意路徑名中的斜槓要雙寫,如:
"D:\\MyFiles\\ReadMe.txt"
文件打開方式選項:
ios::
in
= 0x01,
//供讀,文件不存在則創建(ifstream默認的打開方式)
ios::
out
= 0x02,
//供寫,文件不存在則創建,若文件已存在則清空原內容(ofstream默認的打開方式)
ios::ate = 0x04,
//文件打開時,指針在文件最後。可改變指針的位置,常和in、out聯合使用
ios::app = 0x08,
//供寫,文件不存在則創建,若文件已存在則在原文件內容後寫入新的內容,指針位置總在最後
ios::trunc = 0x10,
//在讀寫前先將文件長度截斷爲0(默認)
ios::nocreate = 0x20,
//文件不存在時產生錯誤,常和in或app聯合使用
ios::noreplace = 0x40,
//文件存在時產生錯誤,常和out聯合使用
ios::binary = 0x80
//二進制格式文件
文件保護方式選擇項:
filebuf::openprot;
//默認的兼容共享方式
filebuf::sh_none;
//獨佔,不共享
filebuf::sh_read;
//讀共享
filebuf::sh_write;
//寫共享
打開文件的方法
調用構造函數時指定文件名和打開模式
ifstream f(
"d:\\12.txt"
,ios::nocreate);
//默認以
ios::in 的方式打開文件,文件不存在時操作失敗
ofstream f(
"d:\\12.txt"
);
//默認以
ios::out的方式打開文件
fstream f(
"d:\\12.dat"
,ios::
in
|ios::
out
|ios::binary);
//以讀寫方式打開二進制文件
使用Open成員函數
fstream f;
f.open(
"d:\\12.txt"
,ios::
out
);
//利用同一對象對多個文件進行操作時要用到open函數
檢查是否成功打開
成功:
if
(f){...}
//對ifstream、ofstream對象可用,fstream對象不可用。
if
(f.good()){...}
失敗:
if
(!f){...}
// !運算符已經重載
if
(f.fail()){...}
讀寫操作
使用<<,>>運算符
只能進行文本文件的讀寫操作,用於二進制文件可能會產生錯誤。
使用函數成員
get
、put、read、write等
經常和read配合使用的函數是gcount(),用來獲得實際讀取的字節數。
讀寫二進制文件注意事項
打開方式中必須指定ios::binary,否則讀寫會出錯
用read\write進行讀寫操作,而不能使用插入、提取運算符進行操作,否則會出錯。
使用eof()函數檢測文件是否讀結束,使用gcount()獲得實際讀取的字節數
關閉文件
使用成員函數close,如:
f.close();
利用析構函數
對象生命期結束時會檢查文件是否關閉,對沒有關閉的文件進行關閉操作。
隨機讀寫文件
通過移動文件讀寫指針,可在文件指定位置進行讀寫。
seekg(絕對位置);
//絕對移動, //輸入流操作
seekg(相對位置,參照位置);
//相對操作
tellg();
//返回當前指針位置
seekp(絕對位置);
//絕對移動, //輸出流操作
seekp(相對位置,參照位置);
//相對操作
tellp();
//返回當前指針位置
參照位置:
ios::beg = 0
//相對於文件頭
ios::cur = 1
//相對於當前位置
ios::end = 2
//相對於文件尾
讀寫文本文件的示例
//爲能夠正確讀出寫入文件的各數據,各數據間最好要有分隔
#include<fstream.h>
void
main()
{
fstream f(
"d:\\try.txt"
,ios::
out
);
f<<1234<<
' '
<<3.14<<
'A'
<<
"How
are you"
;
//寫入數據
f.close();
f.open(
"d:\\try.txt"
,ios::
in
);
int
i;
double
d;
char
c;
char
s[20];
f>>i>>d>>c;
//讀取數據
f.getline(s,20);
cout<<i<<endl;
//顯示各數據
cout<<d<<endl;
cout<<c<<endl;
cout<<s<<endl;
f.close();
}
運行結果:
1234
3.14
A
How are you
Press any key to
continue
顯示文本文件的內容
//使用get()一次讀一個字符--------------------------------方案一
#include<fstream.h>
void
main()
{
ifstream fin(
"d:\\簡介.txt"
,ios::nocreate);
if
(!fin){
cout<<
"File open error!\n"
;
return
;
}
char
c;
while
((c=fin.
get
())!=EOF)
//注意結束條件的判斷
cout<<c;
fin.close();
}
//使用get(char *,int n,char delim='\n')一次讀多個字符----方案二
//巧妙利用文本文件中不會有字符'\0'的特點進行讀取
#include<fstream.h>
void
main()
{
ifstream fin(
"d:\\簡介.txt"
,ios::nocreate);
if
(!fin){
cout<<
"File open error!\n"
;
return
;
}
char
c[80];
while
(fin.
get
(c,80,
'\0'
)!=NULL)
//注意結束條件的判斷
cout<<c;
fin.close();
}
//使用read(char *,int n)讀文件---------------------------方案三
#include<fstream.h>
void
main()
{
ifstream fin(
"d:\\簡介.txt"
,ios::nocreate);
if
(!fin){
cout<<
"File open error!\n"
;
return
;
}
char
c[80];
while
(!fin.eof())
//判斷文件是否讀結束
{
fin.read(c,80);
cout.write(c,fin.gcount());
}
fin.close();
}
定位和獲取當前位置
有的時候,我們需要對文件進行隨機訪問,如連接兩個文件的時候就要定位到文件的末尾。在stl中可以通過stream對象的seekg實現這一功能。與之相對的就是獲取當前位置,函數爲tellg,如下代碼演示了利用這兩個函數獲取文件長度。
input.seekg (0,ios::end);
int length = input.tellg();
tellg函數比較簡單,沒有參數,直接返回當前位置。而seekg有兩個參數:第一個參數是偏移量,可以爲負數;第二個參數則是相對位置,可以選取ios::beg(begin)、ios::end(end)、ios::cur(current)三個值,這個參數可以省略,省略的時候是取的ios::beg,從文件頭定位。
拷貝文件
//二進制文件操作示例
#include<fstream.h>
void
main()
{
ifstream fin(
"C:\\1.exe"
,ios::nocreate|ios::binary);
if
(!fin){
cout<<
"File open error!\n"
;
return
;
}
ofstream fout(
"C:\\2.exe"
,ios::binary);
char
c[1024];
while
(!fin.eof())
{
fin.read(c,1024);
fout.write(c,fin.gcount());
}
fin.close();
fout.close();
cout<<
"Copy over!\n"
;
}
關閉文件
關閉文件有兩個方法:
-
調用close方法顯式關閉
-
對象刪除的時候隱式關閉
具體使用哪個這個看個人喜好了,就我個人而言,我一般喜歡在構造函數中打開文件,不習慣調用open函數,因此也比較傾向於隱式關閉,不調用close函數。