1、文件的讀寫linux
如前面所提,流的讀寫主要有<<, >>, get, put, read, write 等操做,ofstream 繼承自ostream, ifstream 繼承自 istream,故操做函數都是一致的。ios
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <iostream> #include <fstream> #include <string> #include <cassert> using namespace std; int main(void) { ofstream fout("test.txt"); fout << "abc" << " " << 200; fout.close(); ifstream fin("test.txt"); string s; int n; //fin>>n>>s; fin >> s >> n; cout << s << " " << n << endl; ofstream fout1("test2.txt"); assert(fout1); char ch; for (int i = 0; i < 26; i++) { ch = 'A' + i; fout1.put(ch); } fout1.close(); ifstream fin1("test2.txt"); while (fin1.get(ch)) { cout << ch; } cout << endl; return 0; } |
2、二進制文件的讀寫編程
二進制文件不一樣於文本文件,它可用於任何類型的文件(包括文本文件)
對二進制文件的讀寫可採用從istream類繼承下來的成員函數read()和從ostream類繼承下來的成員函數write()
文件打開操做時使用枚舉常量ios::binary,例如:ofstream fout(「binary.dat」,ios::out | ios::binary);
app
(一)、write成員 函數編輯器
函數功能:以字節爲單位向文件流中寫入整塊數據,最有價值的應用能夠處理結構體變量和類對象
函數原型:
函數
ostream& write( const char* pch, int nCount );spa
函數參數:
pch 寫入的數據的指針
nCount 寫入數據的字節大小
.net
(二)、read 成員 函數
指針
函數功能:從文件流中讀出整塊數據
函數原型:
對象
istream& read( char* pch, int nCount );
函數參數:
pch 用來接收數據的指針
nCount 讀取的字節數的大小
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <cassert> #include <iostream> #include <fstream> #include <string> using namespace std; struct Test { int a; int b; }; int main(void) { ofstream fout("test3.txt", ios::out | ios::binary); // 二進制方式打開,'\n'不作轉換 fout << "ABC\n"; // << 是以文本方式寫入 fout.close(); Test test = { 100, 200 }; ofstream fout1("test4.txt", ios::out | ios::binary); fout1.write(reinterpret_cast<char *>(&test), sizeof(Test)); // 二進制方式寫入後用文本編輯器打開test4.txt 亂碼 fout1.close(); Test test2; ifstream fin("test4.txt", ios::in | ios::binary); fin.read(reinterpret_cast<char *>(&test2), sizeof(Test)); cout << test2.a << " " << test2.b << endl; ofstream fout2("test5.txt", ios::out | ios::binary); fout2 << "abc" << 200; // << 是以文本方式寫入 fcout2.close(); return 0; } |
在window下以文本方式打開文件,則以文本方式寫入時遇到'\n' , 轉換爲'\r\n',以二進制方式打開則不作轉換,故test3.txt 文件大小爲4個字節。
而寫入100(write 是以二進制方式寫入)就再也不是寫入'1', '0' ,' 0' 的ascii 碼,而是按照內存原本二進制形式寫入,故用文本編輯器打開test4.txt 時會出
現亂碼。文件大小爲8個字節(兩個int)。同理,test5.txt 雖然以二進制打開,可是以文本方式(<< 是以文本方式寫入)寫入的,故寫入200後用文本
編輯器打開不會出現亂碼,文件大小爲6個字節。
有關文本文件與二進制文件的區別,請參考這裏。
使用read, write 讀取string 的時候須要注意,string 實際上內部是一些指針成員,sizeof(string)=32 (跟編譯器實現有關),即string 大小是必定的,
而它的指針成員保存的字符串長度不必定是32,故咱們應該這些讀寫:
1
2 3 4 5 6 7 8 9 |
string str1 =
"fdsfafsdsf"; int len = str1.length(); ofstream fout("test6.txt", ios::out | ios::binary); fout.write(str1.data(), str1.length()); string str2; str2.resize(len); ifstream fin("test6.txt", ios::in | ios::binary); fin.read(&str2[0], len); |
若是像這樣寫入 fout.write((char*)&str1, sizeof(str1)); 必定是錯誤的,由於寫入的是str1 的指針成員,而不是指針成員指向的字符串,並且str1 的大小恆等於32。
3、文件隨機讀寫
(一)、當前文件流活動指針
文件流指針用以跟蹤發生 I/O 操做的位置
每當從流中讀取或寫入一個字符,當前活動指針就會向前移動
當打開方式中不含有ios::ate或ios::app選項時,則文件指針被自動移到文件的開始位置,即字節地址爲0的位置。
(二)、文件的隨機讀寫 seekp和seekg
seekp 和 seekg 相似與C庫的fseek, linux系統調用的lseek。
函數功能
seekp:設置輸出文件流的文件流指針位置
seekg:設置輸入文件流的文件流指針位置
函數原型:
ostream& seekp( streampos pos );
ostream& seekp( streamoff off, ios::seek_dir dir );
istream& seekg( streampos pos );
istream& seekg( streamoff off, ios::seek_dir dir );
函數參數
pos:新的文件流指針位置值
off:須要偏移的值
dir:搜索的起始位置
dir參數用於對文件流指針的定位操做上,表明搜索的起始位置
在ios中定義的枚舉類型:
enum seek_dir {beg, cur, end};
每一個枚舉常量的含義:
ios::beg:文件流的起始位置
ios::cur:文件流的當前位置
ios::end:文件流的結束位置
tellp 和 tellg 相似C庫的ftell,,linux 系統調用的lseek(fd, 0, SEEK_CUR);
函數功能
tellp:得到輸出的文件流指針的當前位置,以字節爲單位
tellg:得到輸入的文件流指針的當前位置,以字節爲單位
函數原型:
streampos tellp();
streampos tellg();
函數返回值:其實是一個long類型
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <cassert> #include <iostream> #include <fstream> #include <string> using namespace std; int main(void) { ifstream fin("test7.txt"); assert(fin); fin.seekg(2);//位置從0開始計數 char ch; fin.get(ch); cout << ch << endl; fin.seekg(-1, ios::end); //end 其實是EOF位置 fin.get(ch); cout << ch << endl; fin.seekg(0, ios::end); streampos pos = fin.tellg(); cout << pos << endl; return 0; } |
假設test7.txt 如今存放abcdefg 7個字符,則輸出爲c g 7 .
參考:
C++ primer 第四版 Effective C++ 3rd C++編程規範