C++ 在二进制文件中写入和读取类的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2046829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Write and read object of class into and from binary file
提问by Tim
I try to write and read object of class into and from binary file in C++. I want to not write the data member individually but write the whole object at one time. For a simple example:
我尝试在 C++ 中将类的对象写入和读取到二进制文件中。我不想单独写入数据成员,而是一次写入整个对象。举个简单的例子:
class MyClass {
public:
int i;
MyClass(int n) : i(n) {}
MyClass() {}
void read(ifstream *in) { in->read((char *) this, sizeof(MyClass)); }
void write(ofstream *out){ out->write((char *) this, sizeof(MyClass));}
};
int main(int argc, char * argv[]) {
ofstream out("/tmp/output");
ifstream in("/tmp/output");
MyClass mm(3);
cout<< mm.i << endl;
mm.write(&out);
MyClass mm2(2);
cout<< mm2.i << endl;
mm2.read(&in);
cout<< mm2.i << endl;
return 0;
}
However the running output show that the value of mm.i supposedly written to the binary file is not read and assigned to mm2.i correctly
然而,运行输出显示应该写入二进制文件的 mm.i 的值未被读取并正确分配给 mm2.i
$ ./main
3
2
2
So what's wrong with it?
那么它有什么问题呢?
What shall I be aware of when generally writing or reading an object of a class into or from a binary file?
通常在二进制文件中写入或读取类的对象时,我应该注意什么?
采纳答案by R Samuel Klatchko
The data is being buffered so it hasn't actually reached the file when you go to read it. Since you using two different objects to reference the in/out file, the OS has not clue how they are related.
数据正在缓冲,因此在您读取文件时它实际上并未到达文件。由于您使用两个不同的对象来引用输入/输出文件,因此操作系统不知道它们之间的关系。
You need to either flush the file:
您需要刷新文件:
mm.write(&out);
out.flush()
or close the file (which does an implicit flush):
或关闭文件(执行隐式刷新):
mm.write(&out);
out.close()
You can also close the file by having the object go out of scope:
您还可以通过让对象超出范围来关闭文件:
int main()
{
myc mm(3);
{
ofstream out("/tmp/output");
mm.write(&out);
}
...
}
回答by Yann Ramin
Dumping raw data is a terrible idea, from multiple angles. This will break even worse once you add pointer data.
从多个角度转储原始数据是一个糟糕的主意。一旦您添加指针数据,这将变得更糟。
One suggestion would be to use Boost.Serializationwhich allows for far more robust data dumping.
一个建议是使用Boost.Serialization,它允许更强大的数据转储。
Your main problem is the file does not contain the contents yet due to fstream buffering. Close or flush the file.
您的主要问题是由于 fstream 缓冲,该文件尚不包含内容。关闭或刷新文件。
回答by HostileFork says dont trust SE
I'll echo "you shouldn't be doing this". If you print out sizeof(myc)
in the code above it's probably 4, as you'd expect... BUT try changing read and write to be virtual. When I did so, it prints out the size as 16. Those 12 bytes are internal guts with sensitive values—and saving them out and then reading them back in would be like expecting a pointer value to be still good if you wrote it and loaded it again.
我会回应“你不应该这样做”。如果您sizeof(myc)
在上面的代码中打印出它可能是 4,正如您所期望的那样......但是尝试将读取和写入更改为虚拟。当我这样做时,它会打印出大小为 16。这 12 个字节是具有敏感值的内部数据——将它们保存出来然后读回就像期望一个指针值在你编写并加载它时仍然有效再说一遍。
If you want to circumvent serialization and map C++ object memory directly to disk, there are ways to hack that. But rules are involved and it's not for the faint of heart. See POST++ (Persistent Object Storage for C++)as an example.
如果你想绕过序列化并将 C++ 对象内存直接映射到磁盘,有一些方法可以破解。但是涉及规则,它不适合胆小的人。以POST++(C++ 的持久对象存储)为例。
I'll add that you did not check the fail()
or eof()
status. If you had you'd have known you were misusing the fstream API. Try it again with:
我会补充一点,您没有检查fail()
或eof()
状态。如果你知道,你就会知道你在滥用 fstream API。再试一次:
void read(ifstream *in) {
in->read((char *) this, sizeof(myc));
if (in->fail())
cout << "read failed" << endl;
}
void write(ofstream *out){
out->write((char *) this, sizeof(myc));
if (out->fail())
cout << "write failed" << endl;
}
...and see what happens.
...看看会发生什么。