0

バイナリフォーマッタを使用したオブジェクトのシリアライズ/デシリアライズについてお聞きしたいです。さて、1つずつシリアル化された多くのオブジェクトを含む FileStream のオブジェクトを逆シリアル化しようとしています。オブジェクトのサイズが大きすぎてプロセス メモリに保存できないため、次のようにすべてのオブジェクトを 1 つにまとめることはしません。この方法では、すべてのオブジェクトではなく1つのオブジェクトを交互に処理するだけなので、多くのプロセスメモリを必要としません。私が意味するスケッチを見てください

<FileStream>
----Object 1-----Size = 100 Mb------index = 0
----Object 2-----Size = 100 Mb------index = 1
----Object 3-----Size = 100 Mb------index = 2
----Object 4-----Size = 100 Mb------index = 3
----Object 5-----Size = 100 Mb------index = 4
----Object 6-----Size = 100 Mb------index = 5
</FileStream>

オブジェクトのシリアル化も正常に行われ、オブジェクトを逆シリアル化する際に問題が発生しました。ここに問題があります。リストでは、インデックスを持つアイテムを取得できます。したがって、5 番目のインデックスを取りたい場合は、次のように呼び出すことができます。

    List<object> list = new List<object>();
    list(0) = "object1";
    list(1) = "object2";
    list(2) = "object3";
    list(3) = "object4";
    list(4) = "object5";
    list(5) = "object6";
    object fifthIndex = list[5]; // here we can get item based index

問題は、Binary Formatter を使用して、ファイルストリーム内の 6 つの Deserialization オブジェクトのList メソッドのように、5 番目のインデックスを持つオブジェクトを取得する方法です。FileStream には「FileStream.Position」という名前のプロパティがあることは知っていますが、Index が好きではありません。オブジェクトを逆シリアル化/シリアル化すると、乱数のように見えます。多分それは乱数を増やします。

実際に私はこれで成功しましたが、これは私が今まで試した私のコードを見て最善の方法ではないと確信しています:

object GetObjectStream(FileStream fs, int index)
{
    if (fs != null)
    {
        BinaryFormatter binaryformatter = new BinaryFormatter();
        bool isFinished = false; int count = 0;
        while (isFinished == false)
        {
            try
            {
                object objectdeserialized = binaryformatter.Deserialize(fs);
                if (count == index) return objectdeserialized;
                count++;
            }
            catch
            {
                isFinished = true;
                return null;
            }
        }
    }
    return null;
}

これらのコードは、シリアル化されたすべてのオブジェクトを「foreach」し、すべてのオブジェクトを逆シリアル化します。100 MB を含むオブジェクトをデシリアライズするには時間がかかる可能性があるため、コードが最善の方法ではないに違いありません。デシリアライズされるインデックス以外のオブジェクトが破棄されるかどうかさえわかりません。「Serialization Leap」のようなメソッドが欲しい。

この問題を解決できれば、あなたの答えは私にとって非常に役に立ちます。

前にありがとう..

4

2 に答える 2

1

各オブジェクトは、シリアル化するために異なる量のスペースを必要とする可能性が高く、特に文字列や配列などのデータ パックは異なります。基本的に、これを効率的に行うには(つまり、毎回すべてのオブジェクトを完全に読み取ることなく)、次のいずれかを行います。

  • 各オブジェクトに必要なデータ量のプレフィックスを付け、それを にシリアル化しMemoryStream、格納し.Lengthます (都合のよい方法で、4 バイトのリトルエンディアン チャンクで十分です)。次に、書き込んだデータをMemoryStream出力にコピーします。 ; 次に、n 回で n 番目の項目にスキップできます (4 バイトを int として読み取り、そのバイト数をスキップします)。
  • .Position別のインデックスに、各オブジェクトをシリアル化する直前にベース ストリームの を保存します。n 番目のオブジェクトを読み取るには、インデックスを使用して必要な位置を見つけ、そこまでスクロールします。

実際、あなたはここで非常に幸運でした:BinaryFormatter実際には追加しても安全であるとは文書化されていませんが、たまたまそれ行うとうまくいきますが、これはすべてのシリアライゼーション形式に当てはまるわけではありません。

個人的には、ここで使用できる単純な別のデザインがあるかどうか疑問に思います.

于 2013-08-22T14:38:02.500 に答える