2010-01-23 72 views
2

我正在创建一个项目,我正在构建一个几乎类似于对象图的序列化的字节数组。每个类都负责写出它自己的数据,所以我正在考虑使用BinaryWriter并将该实例传递给我的子对象,并让它们自己序列化成此对象,而不是创建临时缓冲区(字节数组)并将它们合并。随机访问和BinaryWriter?

但是我需要在每个子数据前加上一个字节来指定下一个块的大小,但是直到孩子写完所有数据才知道,到那时,写者被定位在孩子数据。我当然可以创建一个临时缓冲区,然后将一个临时BinaryWriter传递给子节点,然后将数据写入“主”BinaryWriter,但这感觉像是一个骇人的解决方案。

是否有任何其他解决办法?篡改BinaryWriter的位置可能不是个好主意吗?我想,以避免创建临时缓冲区/作家如果可能的话,只是让每个孩子写信给我的“主”的作家/缓冲

下面的解决方案可能会奏效,但一点点的hackish。有没有更好的解决方案? (我没有测试过所以有可能不完全字节对齐)

public abstract class BaseObject 
{ 
     public abstract void Serialize(BinaryWriter writer); 
} 



public class Program() 
{ 

    public static void Main() 
    { 
     List<BaseObject> myChildren = new List<BaseObject>(); 

     // ... Initialize children here.. 

     MemoryStream memoryStream = new MemoryStream(); 
     BinaryWriter writer = new BinaryWriter(memoryStream); 

     foreach (BaseObject child in myChildren) { 
      writer.Write((byte)0); // Dummy placeholder. Length is a byte 
      long sizePosition = writer.BaseStream.Position; 
      child.Serialize(writer); 
      long currentPosition = writer.BaseStream.Position; 
      writer.Seek(sizePosition, SeekOrigin.Begin); 
      writer.Write((byte)currentPosition-sizePosition); 
      writer.Seek(currentPosition , SeekOrigin.Begin); 
     } 
    } 
} 
+0

这是因为我没有这个格式。我真正想做的是序列化DHCP选项... – Per 2010-01-23 19:37:04

回答

2

我也被最近一个非常类似的问题难住了,也意识到这似乎可以/应该几乎只有与相关的一个二进制作家因为只要关闭一个二进制编写器(根据文档),流也会关闭。我没有提出比你描述的解决方案更好的解决方案:

  1. 将数据写入MemoryStream,然后将内存流的大小和内容写入主流。如果你想允许一些对象使用BinaryWriter之外的另一种编写器,这可能会很方便。
  2. 请记住您的当前位置,写入0值,然后写入数据块。之后,回退到0值并将其替换为书面大小,然后返回到最后。

我选择了第1号选择。尽管我还没有完成我的实现,但在我写入任何流之前知道要写入什么内容的大小感觉会更好。编写虚拟值并在流中跳跃感觉更有意思。它可能更类似于BinaryWriter如何在内部写字符串。您或您是否考虑过从BinaryWriter继承以添加您自己的写入功能?