【问题标题】:Writing disparate objects to a single file将不同的对象写入单个文件
【发布时间】:2014-02-04 13:26:41
【问题描述】:

这是我在 Pulling objects from binary file and putting in List<T> 发现的问题和 David Torrey 在Serializing and Deserializing Multiple Objects 提出的问题的一个分支。

我不知道这是否可能。假设我有一个应用程序,它使用五个不同的类来包含必要的信息来完成应用程序所做的任何事情。这些类不相互引用,并且具有各种数量的内部变量等。我想将从这些类中生成的对象集合保存到单个保存文件中,然后能够将它们读回。由于对象是从不同的类创建的,因此它们不能进入要发送到磁盘的列表中。我最初认为使用 sizeof(this) 之类的东西来记录对象的大小以记录在一个保存在文件开头的表中,然后有一个通用的 GetObjectType() 来返回一个可操作的值作为对象的种类它本来可以工作,但显然 sizeof 并没有像我想象的那样工作,所以现在我回到了第 1 格。

【问题讨论】:

  • 您能不能只创建一个包含您需要的所有内容的 Settings 对象并使用 XmlSerializer 来序列化/反序列化数据?
  • 你知道,我没有想到这一点。对于我可以预见自己承担的任何类型的项目,我想不出你提出的解决方案不起作用的原因。如果我走得更远,我可能会发现它不适用于编写文件系统,但我认为如果您使用 C# 编写文件系统,还有其他问题。

标签: c# file object serialization deserialization


【解决方案1】:

几个选项:将所有对象包装在一个更大的对象中并将其序列化。这样做的问题是您不能只反序列化一个对象,您必须加载所有对象。如果你有 10 个对象,每个对象都是几兆,那不是一个好主意。您希望随机访问任何对象,但您不知道文件中的偏移量。 “包装器”对象可以像 List&lt;object&gt; 这样简单,但为了更好的类型安全,我会使用自己的对象。

第二个选项:使用固定大小的文件页眉/页脚。将每个对象序列化为 MemoryStream,然后将各个对象的内存流转储到文件中,记住每个对象中的字节数。最后在文件的开头或结尾添加一个固定大小的块来记录文件中各个对象开始的偏移量。在下面的示例中,文件的标题首先包含文件中的对象数量(作为整数),然后是每个对象的一个​​整数,给出每个对象的大小。

// Pseudocode to serialize two objects into the same file

// First serialize to memory    
byte[] bytes1 = object1.Serialize();
byte[] bytes2 = object2.Serialize();    

// Write header:
file.Write(2);              // Number of objects
file.Write(bytes1.Length);  // Size of first object
file.Write(bytes2.Length);  // Size of second object

// Write data:
file.Write(bytes1);
file.Write(bytes2);

objectN 的 offset 是标题的大小加上所有大小的总和,直到 N。所以在这个例子中,要读取文件,你可以像这样读取标题(伪,再次)

numObjs = file.readInt();
for(i=0..numObjs)
    size[i] = file.readInt();

之后,您可以计算并寻找对象 N 的正确位置。

第三个选项:使用为您执行选项 #2 的格式,例如 zip。在 .NET 中,您可以使用 System.IO.Packaging 创建结构化 zip(OPC 格式),或者如果您想滚动自己的 zip 格式,可以使用第三方 zip 库。

【讨论】:

  • 关于选项 #2 的问题:如何确定 C# 中对象的大小,以便在读回时知道起点和终点?
  • 对象的(序列化)大小是序列化它需要多少字节。序列化后你就知道了。我将添加一些伪代码来说明我的意思
猜你喜欢
  • 2016-01-17
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 2023-03-22
相关资源
最近更新 更多