2012-03-07 64 views
2

我正在研究一些遺留代碼,它使用win32 WriteFile()寫入二進制文件中的隨機位置。寫入的偏移量可能會超過文件末尾,在這種情況下,WriteFile()似乎會自動將文件大小擴展到偏移量,然後將數據寫入文件。在讀/寫fstream時尋找/寫入位置時自動擴展文件大小

我想使用std::fstream做相同的,但是當我嘗試seekp()到合適的位置,過去的文件的末尾,在seekp()失敗和隨後write()也將失敗。

所以在我看來,我必須'手動'填充當前EOF和我想要寫入的位置之間的空間。

的代碼看起來是這樣的:

void Save(size_t offset, const Element& element) 
{ 
    m_File.seekp(offset, std::ios_base::beg); 
    m_File.write(reinterpret_cast<const char*>(&element), sizeof(Element)); 
    if (m_File.fail()) { 
     // ... error handling 
    } 
} 

所以是我唯一的選擇爲「手動」寫從目前的EOF高達offset0 S'

回答

1

下面是一個例子,我從MSDN拿起逐字:

// basic_ostream_seekp.cpp 
// compile with: /EHsc 
#include <fstream> 
#include <iostream> 

int main() 
{ 
    using namespace std; 
    ofstream x("basic_ostream_seekp.txt"); 
    streamoff i = x.tellp(); 
    cout << i << endl; 
    x << "testing"; 
    i = x.tellp(); 
    cout << i << endl; 
    x.seekp(2); // Put char in third char position in file 
    x << " "; 

    x.seekp(2, ios::end); // Put char two after end of file 
    x << "z"; 
} 

文件「basic_ostream_seekp.txt」有te ting\0\0z的程序,即結束,你被允許尋求過去的結束文件。

在任何情況下,如果寫入失敗,您可以檢查並查看seekp是否也是如此。如果是這樣,您可以提前檢測到故障。

+0

對不起,遲到接受 - 我最終放棄了基於std :: fstream的代碼,因爲CRT只能分配高達2k的文件句柄,這對我們來說還不夠。至於你的答案 - 從ios :: end尋求確實似乎工作。奇怪從ios :: beg尋求失敗。 – liwp 2012-05-17 13:42:46

+0

我也想過去文件的結尾。我在Windows上測試了VS 2010,在Linux上測試了一些相當新的GCC版本(我們的兩個平臺),'ios :: beg'和'ios :: end'一樣工作[編輯:雖然絕對精確,我想我使用'seekp'的one-arg形式,而不是明確指定'ios :: beg']。也許'ios :: beg'因爲其他原因失敗了liwp?在我的情況下,該文件是用'ios :: in |打開的ios :: out | IOS :: binary';不知道這是否有所作爲。我發現有關'過去文件結束'情況的實際文檔令人沮喪。 – entheh 2013-03-27 23:47:11