2013-03-27 100 views
20

我正在尋找關於seekg()seekp()如何寫入文件的說明。例如說我有一個文件,像這樣:fstream seekg(),seekp()和write()

offset 0: 2 
offset 4: 4 
offset 8: 6 
offset 12: 8 
offset 16: 10 

現在我要打開的文件,並做一些試圖讀取和寫入值。

fstream file; 
file.open("file.txt", fstream::in |fstream::out | fstream::binary); 
file.seekp(0, ios::end) // seek to the end of the file 
int eofOffset = file.tellp(); // store the offset of the end-of-file, in this case 20 

int key = 0; 

file.seekg(12, ios::beg); // set the seek cursor to offset 12 from the beginning of the file 
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 8 
file.seekg(8, ios::beg); // set the seek cursor to offset 8 from the beginning of the file 
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 6 

現在我想寫入文件的末尾。由於seekg()函數只能移動查找光標,我的seekp()光標應該仍然在文件的最後?所以:

int newKey = 12; 
file.write((char *) &newKey, sizeof(int)); 

應該讓我的文件現在看起來像:

offset 0: 2 
offset 4: 4 
offset 8: 6 
offset 12: 8 
offset 16: 10 
offset 20: 12 

現在,如果我選擇尋求偏移,寫它的值作爲偏移量,這是價值會發生什麼我的文件剛剛插入。例如,我想offset 8保持eofOffset = 20,因爲我們剛剛在該偏移處插入了12。

如果我做的:

file.seekp(8, ios::beg); 
file.write((char *) &eofOffset, sizeof(int)); 

它正確地重寫我的文件看起來像這樣:

offset 0: 2 
offset 4: 4 
offset 8: 20 
offset 12: 8 
offset 16: 10 
offset 20: 12 

請讓我知道如果我提出用seekg()seekp()功能的任何錯誤。

回答

21

類模板std::basic_filebuf保存單個文件位置

§27.9.1.1

  1. 類basic_filebuf聯營兩個輸入 序列和與文件輸出序列。
  2. 由basic_filebuf類對象控制的讀寫順序的限制與用標準C庫FILE讀取和寫入 相同。
  3. 特別是:
    • 如果文件沒有打開讀取輸入序列不能被讀取。
    • 如果文件未打開寫入輸出序列無法寫入。
    • 爲輸入序列和輸出序列都保留一個聯合文件位置。

這意味着,當你使用一個std::basic_fstream,默認情況下使用std::basic_filebuf,單個文件的位置由兩個seekp()seekg()移動;除非您使用單獨的變量來存儲其中一個頭寸,然後再回頭查找頭寸,否則無法獨立跟蹤頭寸並獲取頭寸。

第2點的含義是在fstream上讀取和寫入之間,您必須刷新緩衝區或在從輸出更改爲輸入時查找文件位置,並且必須位於文件末尾或查找文件位置從輸入更改爲輸出時。

有關這些限制的詳細信息,請參見C99標準(「fopen函數」)的7.19.5.3/7或C11的7.21.5.3/7。

+0

謝謝!那麼你什麼時候會推薦刷新緩衝區?你會在每次讀寫之後刷新它,或者如果你正在進行一系列讀取或一系列寫入,它會保持原樣嗎? – raphnguyen 2013-03-28 18:50:10

+1

@raphnguyen刷新緩衝區是一個相對昂貴的操作,通常不需要手動刷新,除非您正在從寫入切換到讀取,並且您不尋找,除非您有充足的理由刷新讓實現處理其他刷新。 – user657267 2013-03-28 22:25:24