2


0

ランダムアクセスとBinaryWriter

私は、オブジェクトグラフのシリアル化のようなバイト配列を作成するプロジェクトに取り組んでいます。 各クラスは独自のデータを書き出す役割を担っているため、BinaryWriterを使用して、そのインスタンスを子オブジェクトに渡し、一時バッファー(バイト配列)を作成してそれらをマージする代わりに、このインスタンスをシリアル化することを考えています。

ただし、各子データの先頭に次のブロックのサイズを指定するバイトを追加する必要がありますが、これは子がすべてのデータを書き込むまでわからず、その時点でライターは子データの最後に配置されます。 もちろん、一時バッファーを作成し、一時BinaryWriterを子に渡し、その後、データを "メイン" BinaryWriterに書き込むこともできますが、それはハック的なソリューションのように感じます。

代替ソリューションはありますか? BinaryWriterの位置を改ざんするのは悪い考えでしょうか? 可能な場合は一時的なバッファ/ライターの作成を避け、各子が「メイン」ライター/バッファに書き込むようにします

以下のソリューションは動作するかもしれませんが、少しハックです。 より良い解決策はありますか? (私はそれをテストしていないので、おそらく完全にバイトアラインされていないでしょう)

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



public class Program()
{

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

       // ... 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);
       }
   }
}

1 Answer


2


私も最近、非常に似た質問に悩まされ、特定のストリームに関連付けられたバイナリライターを実際に1人しか持つことができない/必要があることに気づきましたまた閉じた。 あなたが説明したものよりも良い解決策はありません。

  1. データをMemoryStreamに書き込み、次にサイズと内容を書き込みます メインストリームへのメモリストリーム。 これは、一部のオブジェクトがBinaryWriter以外の別の種類のライターを使用できるようにする場合に便利です。

  2. 現在位置を覚えて、値0を書き込んでから、データブロックを書き込みます。 その後、0の値まで巻き戻し、書き込まれたサイズに置き換えてから、最後に戻ります。

選択肢1を選択しました。 まだ実装を完了していませんが、ストリームに何かを書き込む前に、書き込まれる内容のサイズを知っている方が良いと感じています。 ダミー値を書き込んでストリームを飛び回るのがより不自然に感じられます。 そして、おそらくBinaryWriterが内部で文字列を書き込む方法により似ています。 BinaryWriterから継承して独自の書き込み関数を追加しますか、または考慮しましたか?