我们需要BSON的等效内容。
但我们得到的是:
如你所见,有效载荷在头部之前!
我们正在使用Json.NET的BSON编写器(Bson.BsonWriter.WriteValue(byte[] value)),但它只接受实际的byte[],而不是Stream。由于我们的有效载荷将达到数十GB,我们必须使用流,因此我们已经尝试解决这个问题(下面的代码),但这给我们带来了上面显示的不正确结果。
这似乎是没有同步/刷新缓冲区的典型情况,尽管我们在将有效载荷写入底层流之前实际上发出了Json.NET的Flush命令。
问题:还有其他方法吗?我们不想分叉Json.NET的源代码(并探索其内部管道)或以某种方式重新发明轮子...
详细信息:支持结构类是(如果您想要重现此问题):
{
"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; }
}
BsonWriter
仅在对象的末尾写入数据(请参见BsonWriter.WriteEnd
)。看起来你需要将其复制到你的项目中,并修改相当多的类(BsonWriter
,BsonBinaryWriter
,整个BsonToken
层次结构等),以实现写入流,因为它们不是设计成可扩展的。这个功能看起来非常有用,所以我建议修改库的代码并发起一个 pull request。顺便说一下,会有一些限制;其中一个要求是流需要支持告诉它的长度。 - Athari