2

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

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

有没有替代解决方案?篡改 BinaryWriter 的位置可能是个坏主意吗?如果可能的话,我想避免创建临时缓冲区/写入器,只让每个孩子写入我的“主要”写入器/缓冲区

下面的解决方案可能有效,但有点骇人听闻。有没有更好的解决方案?(我还没有测试过,所以可能没有完美的字节对齐)

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);
       }
   }
}
4

1 回答 1

2

我最近也被一个非常相似的问题难住了,并且还意识到您似乎可以/实际上也应该只有一个二进制写入器与特定流相关联,因为一旦您关闭一个二进制写入器(根据文档),流就是也关闭了。我没有比你描述的更好的解决方案:

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

我选择了选项 1。虽然我还没有完成我的实现,但在向流中写入任何内容之前知道要写入的内容的大小对我来说感觉更好。编写虚拟值并在流中跳跃感觉更加做作。它可能更类似于 BinaryWriter 在内部写入字符串的方式。您是否或考虑过从 BinaryWriter 继承以添加您自己的 Write 函数?

于 2010-01-23T15:23:03.343 回答