另一种序列化的方式
原文:http://james.newtonking.com/archive/2009/12/26/json-net-3-5-release-6-binary-json-bson-support.aspx
引言:
在日常工作中经常发现要序列化实体的情况,因此一直在找一种高效的序列化方法。之前看过JSON.NET与ProtoBuf。 最近再看MongiDB的时候发现他们的存储时BSON,一种二进制的Json。这里翻译一篇文章给大家做个介绍,随后再撰文描述各种序列化方法在效率上的对比。
Json.NET 3.5 Release 6以后就对BSON进行了支持,下载地址为:http://json.codeplex.com/releases/view/43775,你可以通过Json.Net来读写Bson文件,Bson当前支持的类型有对象,数组,字符串,整形等,总之以往可序列化为Json的都能序列化为BJSON。
Bson支持一些附加的类型,像二进制数据将被转换成Json。
Bson显著优于Json的特征有两个就是序列化后的大写和序列化的速度。它直接存储二进制数据避免了Json对数据进行base64编码的额外开销并且读写Bson比Json更快。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z");
p.Name = "Carlos' Spicy Wieners";
p.Price = 9.95m;
p.Sizes = new[] { "Small", "Medium", "Large" };
MemoryStream ms = new MemoryStream();
JsonSerializer serializer = new JsonSerializer();
// serialize product to BSON
BsonWriter writer = new BsonWriter(ms);
serializer.Serialize(writer, p);
Console.WriteLine(BitConverter.ToString(ms.ToArray()));
// 7C-00-00-00-02-4E-61-6D-65-00-16-00-00-00-43-61-72-6C-
// 6F-73-27-20-53-70-69-63-79-20-57-69-65-6E-65-72-73-00-
// 09-45-78-70-69-72-79-44-61-74-65-00-E0-51-BD-76-20-01-
// 00-00-01-50-72-69-63-65-00-66-66-66-66-66-E6-23-40-04-
// 53-69-7A-65-73-00-2D-00-00-00-02-30-00-06-00-00-00-53-
// 6D-61-6C-6C-00-02-31-00-07-00-00-00-4D-65-64-69-75-6D-
// 00-02-32-00-06-00-00-00-4C-61-72-67-65-00-00-00
ms.Seek(0, SeekOrigin.Begin);
// deserialize product from BSON
BsonReader reader = new BsonReader(ms);
Product deserializedProduct = serializer.Deserialize<Product>(reader);
Console.WriteLine(deserializedProduct.Name);
// Carlos' Spicy Wieners
json.net不再依赖于实体框架,Link to Sql或是第三方的程序集。同时它可以再.net4.0的下运行,操作办法见http://blogs.msdn.com/b/endpoint/archive/2009/10/21/client-profile-in-net-4.aspx。
Json.Net当前自动序列化和反序列化DataSet和DataTable.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
ds.Tables.Add(CreateDataTable("FirstTable", 2));
ds.Tables.Add(CreateDataTable("SecondTable", 1));
string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new IsoDateTimeConverter());
// {
// "FirstTable": [
// {
// "StringCol": "Item Name",
// "Int32Col": 1,
// "BooleanCol": true,
// "TimeSpanCol": "10.22:10:15.1000000",
// "DateTimeCol": "2000-12-29T00:00:00Z",
// "DecimalCol": 64.0021
// },
// {
// "StringCol": "Item Name",
// "Int32Col": 2,
// "BooleanCol": true,
// "TimeSpanCol": "10.22:10:15.1000000",
// "DateTimeCol": "2000-12-29T00:00:00Z",
// "DecimalCol": 64.0021
// }
// ],
// "SecondTable": [
// {
// "StringCol": "Item Name",
// "Int32Col": 1,
// "BooleanCol": true,
// "TimeSpanCol": "10.22:10:15.1000000",
// "DateTimeCol": "2000-12-29T00:00:00Z",
// "DecimalCol": 64.0021
// }
// ]
// }
DataSet deserializedDs = JsonConvert.DeserializeObject<DataSet>(json, new IsoDateTimeConverter());
SelectToken提供一种类似Xpath的语句来对数据进行查找。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
""Stores"": [
""Lambton Quay"",
""Willis Street""
],
""Manufacturers"": [
{
""Name"": ""Acme Co"",
""Products"": [
{
""Name"": ""Anvil"",
""Price"": 50
}
]
},
{
""Name"": ""Contoso"",
""Products"": [
{
""Name"": ""Elbow Grease"",
""Price"": 99.95
},
{
""Name"": ""Headlight Fluid"",
""Price"": 4
}
]
}
]
}");
string name = (string)o.SelectToken("Manufacturers[0].Name");
// Acme Co
decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price");
// 50
string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
// Elbow Grease