6

我想自己实现二进制序列化,不使用Boost或任何其他第三方库。

在 C++ 中,实现它的最简单方法是使用ofstream然后通过网络发送二进制文件。但是是否有任何其他流类可以用作临时缓冲区以避免将文件写入磁盘?

另外,我怎样才能在纯 C 中实现这一点?

4

4 回答 4

16

坚持是个难题。甚至将对象序列化到磁盘也并非易事。假设,例如,您在 C 中有这样的结构:

struct Person {
    char name[100];
    int year;
};

这是一个包含 sef 的结构,可能是真正应用序列化的最简单方法。但是,您将不得不面对以下问题:

  1. 编译器的填充系统。在内存中完成一个结构以使其占用内存中的整数个字的方法是不标准的。

  2. 操作系统和机器本身以二进制形式表示数据的方式。显然,这种表示从一台机器变为另一台机器。

结论是,即使是由同一操作系统中的同一程序创建的文件也可能与同一操作系统中的同一程序不兼容,因为可能两个程序是用不同的 C 编译器编译的。

现在让我们看看 C++ 中的一个对象:

class Person {
public:
    // more things...

private:
    string name;
    Date * birth;
    Firm * firm;
};

现在同样的事情变得非常复杂。对象不再是自包含的,你应该按照指针来决定如何处理每个对象(这被称为 3. 指针混合和传递持久性)。你仍然有 1) 和 2) 的问题。

因此,假设您专注于自包含对象,并且仍然需要针对第 1 点和第 2 点的解决方案。唯一的方法是确定 a) 文本格式或 b) 字节码格式的表示。字节码格式可以被任何操作系统中的任何程序理解,用任何 C 编译器编译,因为信息是逐字节读取和写入的。这是 Java 或 C# 序列化其对象的方式。作为表示的文本格式与字节码一样有效,但速度较慢。它的主要优点是它可以被人和计算机理解(结构化文本格式可以是 XML)。

因此,为了序列化您的自包含对象,无论选择何种输出格式,您都需要具有能够读取整数、字符、字符串等的基本函数(或 C++ 中的类)。当您拥有每个对象的写/读对时,您必须为程序员提供为她的对象创建她自己的写/读对的可能性,使用您对元素数据的读/写对。

我们在这里谈论的是一个完整的框架,就像 Python 提供的pickle模块一样。

最后,能够缓存您的序列化而不是将其保存到磁盘这一事实是您的问题中最少的。如果您使用的是基于文本的格式,则可以使用ostringstream该类;如果您使用的是字节码,则可以使用内存块。

如您所见,这不是一项简单的工作。希望这可以帮助。

于 2012-06-12T19:35:55.723 回答
3

我一直在使用 JSON 来序列化数据。这很简单,这是一件非常好的事情。很容易让 JSON 正确,并且很容易判断它是否有任何问题。

它不像其他格式那样节省空间,但对于许多用途来说已经足够了。您可以从 JSON 网站获得免费的库代码。

http://json.org/

于 2012-06-12T19:48:03.510 回答
2

在纯 C 中,您可以使用Binn格式。

示例代码:

  binn *obj;

  // create a new object
  obj = binn_object();

  // add values to it
  binn_object_set_int32(obj, "id", 123);
  binn_object_set_str(obj, "name", "John");
  binn_object_set_double(obj, "total", 2.55);

  // send over the network or save to a file...
  send(sock, binn_ptr(obj), binn_size(obj));

  // release the buffer
  binn_free(obj);

免责声明:我是创造者

于 2019-06-08T05:29:07.317 回答
-5

在某些情况下,在处理简单类型时,您可以这样做:

object o; 
socket.write(&o, sizeof(o)); 
于 2012-07-04T13:00:29.023 回答