另一种序列化的方式

原文: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更快。

代码
Product p = new Product();
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.

代码
DataSet ds = new DataSet();
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的语句来对数据进行查找。

string name = (string)o.SelectToken("Manufacturers[0].Name");

 

代码
JObject o = JObject.Parse(@"{
  ""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

 

        

posted @ 2010-07-14 10:47  李占卫  阅读(2251)  评论(0编辑  收藏  举报