2012-03-07 36 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