微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 使用流通过Json.NET创建BSON字节数组(用于文件格式)

我们需要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.由于我们的有效载荷将是10的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,dummyPayload.Length);

        // End
        bw.WriteEndobject();
    }    
}

这看起来像没有同步/不刷新缓冲区的经典情况,尽管我们在将有效负载写入底层流之前实际发出了Flush to Json.NET.

问题:还有其他办法吗?我们宁愿不分叉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; }
}

解决方法

好的,所以我们在这里达到了一些中间地带,因为我们没有时间(目前)修复其他优秀的Json.NET库.由于我们很幸运只有最后的流,我们现在使用BSON作为标题(小到足够一个byte [])然后将它传递给标准流编写器,即表示为:

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

拥有统一的BSON布局会更美观,但如果没有它,这也很有效.可能也快一点!如果有人在将来仍能找到更好的答案,我们正在倾听.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐