【问题标题】:Random access and BinaryWriter?随机访问和 BinaryWriter?
【发布时间】:2010-01-23 15:11:18
【问题描述】:

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

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

是否有任何替代解决方案?篡改 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);
       }
   }
}

【问题讨论】:

  • 那是因为我不拥有该格式。我真正想做的是序列化 DHCP 选项...

标签: c# .net binary-data


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2016-06-07
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多