【问题标题】:C++ binary fstream for read and write doesn't work用于读写的 C++ 二进制 fstream 不起作用
【发布时间】:2011-11-30 19:54:20
【问题描述】:

示例代码如下:

typedef struct myStruct 
{
     int field;
} MyStruct;

功能:

fstream infile (filename.c_str(), ios::in | ios::out | ios::binary);
if (!infile.is_open())
{
    cout << "Error: Failed to open " << filename;
    return false;
}

MyStruct mystruc;
int size = sizeof(mystruc);

// get number of records in file
infile.seekg(0, ios::end);
int count = infile.tellg() / size;
infile.seekg(0,ios::beg);

for (int i = 0; i < count; ++i)
{
    infile.read(reinterpret_cast<char*>(&mystruc), size);
    if (infile.good())
    {
        mystruct.field += 100;

        infile.seekp(size*-1, ios::cur);
        infile.write(reinterpret_cast<char*>(&mystruc), size);
        //infile.flush(); 
    }
}

infile.close();

假设输入文件包含 4 个带有字段值的 MyStruct 记录 1 2 3 4

输出是: 101 102 102 102

而不是: 101 102 103 104

为什么 seekp 不起作用?它可以在每次写入后刷新,但刷新不会减慢功能?

【问题讨论】:

  • 我的猜测——您的问题可能与缓冲 C++ 流的方式有关。冲洗将缓冲排除在等式之外,然后“起作用”。是的,刷新会使函数变慢,但在这个简单的示例中,无论如何您都将等待大量磁盘 IO。
  • 我自己前段时间在一个简单的数据库库的基础层尝试使用C++流时遇到了很多问题(例如更新后遇到那种wtf检索)。我记得我把它改成了 cstdio(std::fopen、std::fread、std::fwrite、std::fseek、std::fclose),一切又神奇地工作了。从那以后,我再也没有使用过 C++ 流,没有什么大不了的。请注意,我并不是说 C++ 或其流有任何不好的地方,这只是我的经验。

标签: c++ fstream


【解决方案1】:

您的结构应该使用pragma pack 打包到一个 1 字节的边界。另外,我很确定您不需要typedef

试试这样的:

#pragma pack(push,1)
struct myStruct 
{
     int field;
}
#pragma pack(pop)  // return to original packing

【讨论】:

  • 我认为在这种情况下不需要打包,因为 int 的大小是 2 的幂,因此这个结构将具有相同的大小。打包不会有任何影响。根据结构包装和便携性要求,可能需要也可能不需要。 typedef 不是必需的,它是 C 风格的。
猜你喜欢
  • 2015-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 2013-07-10
相关资源
最近更新 更多