C++ 如何在C++中将对象写入文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2376193/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:14:27  来源:igfitidea点击:

How to write an object to file in C++

c++fileobjectstring

提问by neuromancer

I have an object with several text strings as members. I want to write this object to the file all at once, instead of writing each string to file. How can I do that?

我有一个包含多个文本字符串作为成员的对象。我想一次将此对象写入文件,而不是将每个字符串写入文件。我怎样才能做到这一点?

采纳答案by stefanB

You can override operator>>and operator<<to read/write to stream.

您可以覆盖operator>>operator<<读取/写入流。

Example Entry structwith some values:

Entry struct一些值的例子:

struct Entry2
{
    string original;
    string currency;

    Entry2() {}
    Entry2(string& in);
    Entry2(string& original, string& currency)
        : original(original), currency(currency)
    {}
};


istream& operator>>(istream& is, Entry2& en);
ostream& operator<<(ostream& os, const Entry2& en);

Implementation:

执行:

using namespace std;

istream& operator>>(istream& is, Entry2& en)
{
    is >> en.original;
    is >> en.currency;
    return is;
}

ostream& operator<<(ostream& os, const Entry2& en)
{
    os << en.original << " " << en.currency;
    return os;
}

Then you open filestream, and for each object you call:

然后打开文件流,并为每个对象调用:

ifstream in(filename.c_str());
Entry2 e;
in >> e;
//if you want to use read: 
//in.read(reinterpret_cast<const char*>(&e),sizeof(e));
in.close();

Or output:

或输出:

Entry2 e;
// set values in e
ofstream out(filename.c_str());
out << e;
out.close();

Or if you want to use stream readand writethen you just replace relevant code in operators implementation.

或者,如果您想使用流readwrite那么您只需替换operators 实现中的相关代码。

When the variables are private inside your struct/class then you need to declare operators as friend methods.

当变量在您的结构/类中是私有的时,您需要将operators声明为友元方法。

You implement any format/separators that you like. When your string include spaces use getline() that takes a string and stream instead of >>because operator>>uses spaces as delimiters by default. Depends on your separators.

您可以实现您喜欢的任何格式/分隔符。当您的字符串包含空格时,请使用 getline() 接受字符串和流而不是>>因为operator>>默认情况下使用空格作为分隔符。取决于你的分隔符。

回答by Chris H

It's called serialization. There are many serialization threads on SO.

这叫做序列化。SO 上有许多序列化线程。

There are also a nice serialization library included in boost.

boost中还包含一个不错的序列化库。

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html

basically you can do

基本上你可以做

myFile<<myObject 

and

myFile>>myObject

with boost serialization.

带有增强序列化。

回答by user205666

If you have:

如果你有:

struct A {
    char a[30], b[25], c[15];
    int x;
}

then you can write it all just with write(fh, ptr, sizeof(struct a)).

然后你就可以用 write(fh, ptr, sizeof(struct a)) 写出来。

Of course, this isn't portable (because we're not saving the endieness or size of "int," but that may not be an issue for you.

当然,这不是可移植的(因为我们没有保存“int”的大小或大小,但这对您来说可能不是问题。

If you have:

如果你有:

struct A {
    char *a, *b, *c;
    int d;
}

then you're not looking to write the object; you're looking to serialize it. Your best bet is to look in the Boostlibraries and use their serialization routines, because it's not an easy problem in languages without reflection.

那么你不想写对象;你正在寻找序列化它。最好的办法是查看Boost库并使用它们的序列化例程,因为在没有反射的语言中这不是一个容易的问题。

回答by KiNgMaR

There's not really a simple way, it's C++ after all, not PHP, or JavaScript.

没有真正简单的方法,毕竟是 C++,而不是 PHP 或 JavaScript。

http://www.parashift.com/c++-faq-lite/serialization.html

http://www.parashift.com/c++-faq-lite/serialization.html

Boost also has some library for it: http://www.boost.org/doc/libs/release/libs/serialization... like Tronic already mentioned :)

Boost 也有一些库:http: //www.boost.org/doc/libs/release/libs/serialization...就像已经提到的 Tronic :)

回答by Thomas Matthews

The better method is to write each field individually along with the string length.

更好的方法是将每个字段与字符串长度一起单独写入。

As an alternative, you can create a chararray (or std::vector<char>) and write all the members into the buffer, then write the buffer to the output.

作为替代方案,您可以创建一个char数组(或std::vector<char>)并将所有成员写入缓冲区,然后将缓冲区写入输出。

The underlying thorn is that a compiler is allowed to insert padding between members in a class or structure. Use memcpyor std::copywill result in padding bytes written to the output.

潜在的问题是允许编译器在类或结构中的成员之间插入填充。使用memcpyorstd::copy将导致写入输出的填充字节。

Just remember that you need to either write the string lengths and the content or the content followed by some terminating character.

请记住,您需要编写字符串长度和内容或内容后跟一些终止字符。

Other people will suggest checking out the Boost Serialization library.

其他人会建议查看 Boost Serialization 库。

回答by Tronic

Unfortunately that is generally not quite possible. If your struct only contains plain data (no pointers or complex objects), you can store it as a one chunk, but care must be taken if portability is an issue. Padding, data type size and endianess issues make this problematic.

不幸的是,这通常不太可能。如果您的结构只包含纯数据(没有指针或复杂对象),您可以将其存储为一个块,但如果可移植性是一个问题,则必须小心。填充、数据类型大小和字节顺序问题使这成为问题。

You can use Boost.Serialization to minimize the amount of code required for proper portable and versionable searialization.

您可以使用 Boost.Serialization 来最小化适当的可移植和可版本化序列化所需的代码量。

回答by Jeremy Friesner

Assuming your goal is as stated, to write out the object with a single call to write() or fwrite() or whatever, you'd first need to copy the string and other object data into a single contiguous block of memory. Then you could write() that block of memory out with a single call. Or you might be able to do a vector-write by calling writev(), if that call is available on your platform.

假设您的目标如上所述,要通过一次调用 write() 或 fwrite() 或其他方法写出对象,您首先需要将字符串和其他对象数据复制到单个连续的内存块中。然后,您可以通过一次调用 write() 该内存块。或者,如果该调用在您的平台上可用,您也可以通过调用 writev() 来执行向量写入。

That said, you probably won't gain much by reducing the number of write calls. Especially if you are using fwrite() or similar already, then the C library is already doing buffering for you, so the cost of multiple small calls is minimal anyway. Don't put yourself through a lot of extra pain and code complexity unless it will actually do some good...

也就是说,通过减少写入调用的数量,您可能不会获得太多收益。特别是如果你已经在使用 fwrite() 或类似的东西,那么 C 库已经在为你做缓冲,所以多次小调用的成本无论如何都是最小的。不要让自己经历很多额外的痛苦和代码复杂性,除非它实际上会产生一些好处......