4

に相当するBSONが必要です

{
    "Header": {
        "SubHeader1": {
            "Name": "Bond",
            "License": 7
        },
        "SubHeader2": {
            "IsActive": true
        }
    },
    "Payload": /* This will be a 40GB byte stream! */
}

しかし、得られるものは次のとおりです。

ここに画像の説明を入力

ご覧のとおり、ペイロードが最初に来て、次に残りのヘッダーが来ます!

Json.NET の BSON ライター ( Bson.BsonWriter.WriteValue(byte[] value)) を使用していますが、実際の のみを受け入れ、 は受け入れbyte[]ませんStream。ペイロードは数十 GB になるため、ストリームを使用する必要があるため、回避策 (以下のコード) を試みましたが、上記の誤った結果が得られます。

public void Expt()
{
    // Just some structure classes, defined below
    var fileStruct = new FileStructure();

    using (Stream outputSt = new FileStream("TestBinary.bson", FileMode.Create))
    {
        var serializer = new JsonSerializer();
        var bw = new BsonWriter(outputSt);

        // Start
        bw.WriteStartObject();

        // Write header            
        bw.WritePropertyName("Header");
        serializer.Serialize(bw, fileStruct.Header);

        // Write payload
        bw.WritePropertyName("Payload");
        bw.Flush(); // <== flush !                
        // In reality we 40GB into the stream, dummy example for now
        byte[] dummyPayload = Encoding.UTF8.GetBytes("This will be a 40GB byte stream!");
        outputSt.Write(dummyPayload, 0, dummyPayload.Length);

        // End
        bw.WriteEndObject();
    }    
}

これは、ペイロードを基になるストリームに書き込む前に Json.NET に Flush を実際に発行しているにもかかわらず、同期がない/バッファをフラッシュしないという典型的なケースのように見えます。

質問: これを行う別の方法はありますか? Json.NET のソースを分岐したり (内部配管を調査したり)、何らかの方法で車輪を再発明したりしたくありません ...


詳細: サポートする構造クラスは (これを再現したい場合)

public class FileStructure
{
    public TopHeader Header { get; set; }
    public byte[] Payload { get; set; }

    public FileStructure()
    {
        Header = new TopHeader
            {
                SubHeader1 = new SubHeader1 {Name = "Bond", License = 007},
                SubHeader2 = new SubHeader2 {IsActive = true}
            };
    }
}

public class TopHeader
{
    public SubHeader1 SubHeader1 { get; set; }
    public SubHeader2 SubHeader2 { get; set; }
}

public class SubHeader1
{
    public string Name { get; set; }
    public int License { get; set; }
}

public class SubHeader2
{
    public bool IsActive { get; set; }
}
4

1 に答える 1

1

わかりました。ここで中間点に到達しました。これは、他の点では優れた Json.NET ライブラリを修正する時間が (現時点では) ないためです。Stream が最後にあるのは幸運だったので、ヘッダーに BSON を使用し ( a に十分小さいbyte[])、それを標準のストリーム ライターに渡します。つまり、表現は次のとおりです。

{
    "SubHeader1": {
        "Name": "Bond",
        "License": 7
    },
    "SubHeader2": {
        "IsActive": true
    }
} /* End of valid BSON */
// <= Our Stream is written here, raw byte stream, no BSON

統一された BSON レイアウトを使用する方が美的でしたが、それがなくても、これはうまく機能します。おそらくもう少し速いです!今後も誰かがより良い答えを見つけたら、私たちは耳を傾けます。

于 2013-06-14T16:42:52.267 に答える