【问题标题】:Why is this binary file write cutting off the end of my file?为什么这个二进制文件写入会切断我的文件末尾?
【发布时间】:2019-12-09 12:05:40
【问题描述】:

所以,我所做的是创建一个结构数组。然后我将该数组写入二进制文件。我认为寻找文件中的第二个结构并覆盖它。然后我将文件读回一个单独的结构数组并将其打印到屏幕上。

写入完成后,文件大小从 24 字节变为 16 字节,第一个结构损坏,最后一个结构从文件中丢失。

这是我的代码:

#include<fstream>
#include<iostream>
using namespace std;

struct Point
{
    int x, y;
};

void print(const Point& p)
{
    cout << "(" << p.x << ", " << p.y << ")" << endl;
}

int main()
{
    Point p[] = {{1, 2}, {3, 4}, {5, 6}};

    for(auto a : p)
        print(a);

    // write array p to file
    fstream f("points.dat", ios::binary | ios::out);
    if(f)
    {
        f.write(reinterpret_cast<char*>(p), 3 * sizeof(Point));
        f.close();
    }

    // read second struct from file and print it to screen
    f.open("points.dat", ios::binary | ios::in);
    if(f)
    {
        Point p;
        f.seekg( 1 * sizeof(Point), ios::beg);
        f.read(reinterpret_cast<char*>(&p), sizeof(Point));
        f.close();
        print(p);
    }

    // change ios::out to ios::ate and it works fine...
    f.open("points.dat", ios::binary | ios::out);
    if(f)
    {
        Point p ={-1, -2};
        f.seekp(1 * sizeof(Point), ios::beg);
        // attempting to overwrite the second struct in the file 
        // shrinks the file from 24 bytes to 16, losing the last
        // struct in the file and causing the first struct to have
        // 0's in it's fields.
        f.write(reinterpret_cast<char*>(&p), sizeof(Point));
        f.close();
    }


    Point q[3];
    // read the file back into q and print q for testing.
    f.open("points.dat", ios::binary | ios::in);
    if(f)
    {
        // fails because the file is now only 16 bytes, instead of 24 
        f.read(reinterpret_cast<char*>(q), 3 * sizeof(Point));      
        f.close();

        for(auto a : q)
            print(a);
    }   
}

烦人的部分是当我将 ios::out 更改为 ios::ate 时,它​​工作得很好。

【问题讨论】:

  • 虽然(IIRC)ios::out(和其他标志)的使用是实现定义的,但我认为使用ios::out隐式添加ios::truncseekp 被忽略。 (对于旧的fopen 模式标志“w”当然是正确的。)

标签: c++ file struct binary


【解决方案1】:

binary|out is the same as binary|out|trunc.

也就是说,默认情况下,当您使用该标志组合时,您的文件会被截断。

  • 如果你只想追加,你想要binary|out|app
  • 否则,您需要binary|out|in

是的,我知道你没有在看书。是的,对于第二个选项,该文件必须已经存在。是的,这很奇怪。

【讨论】:

    【解决方案2】:

    因为当您使用binary|out 打开一个文件并且该文件已经存在时,它会破坏其内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2014-10-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      相关资源
      最近更新 更多