前面介紹了幾個序列化的方式,而dotNet也提供了壓縮的方法,我就在想是不是可以在序列化之後順便壓縮一下呢。

實際做的時候才發覺有許多問題,查了網上其他人的寫法,程式都變得落落長,其實都是利用串流Stream做出來的,怎麼會搞成那麼複雜。在多次修改之後終於有了最後的版本。

   1: static public class SerializeBinaryZipFile {
   2:     /// <summary>
   3:     /// 將物件序列化為二進位格式壓縮檔案
   4:     /// </summary>
   5:     /// <param name="o">原始物件</param>
   6:     /// <param name="filename">檔案名稱</param>
   7:     static public void Serialize(object o, string filename) {
   8:         IFormatter formater = new BinaryFormatter();
   9:         FileStream fileStream = new FileStream(filename, FileMode.Create);
  10:         GZipStream gzipStream = new GZipStream(fileStream, CompressionMode.Compress);
  11:         formater.Serialize(gzipStream, o);            //將物件序列化至內存流
  12:  
  13:         gzipStream.Flush();
  14:  
  15:         gzipStream.Dispose();
  16:         fileStream.Dispose();
  17:  
  18:     }
  19:  
  20:     /// <summary>
  21:     /// 將二進位格式壓縮檔案反序列化為物件
  22:     /// </summary>
  23:     /// <typeparam name="T">物件類別</typeparam>
  24:     /// <param name="filename">檔案名稱</param>
  25:     /// <returns>物件實例</returns>
  26:     static public T Deserialize<T>(string filename) {
  27:         if (!File.Exists(filename)) return default(T);
  28:         try {
  29:             FileStream fileStream = new FileStream(filename, FileMode.Open);
  30:             GZipStream gzipStream = new GZipStream(fileStream, CompressionMode.Decompress);
  31:             IFormatter formater = new BinaryFormatter();
  32:             object obj = formater.Deserialize(gzipStream);
  33:             gzipStream.Dispose();
  34:             fileStream.Dispose();
  35:  
  36:             return (T)obj;
  37:         }
  38:         catch {
  39:             return default(T);
  40:         }
  41:     }

 

重點就在於第13行,要把壓縮串流整個都推出去,這樣寫出去的檔案才完整。不過呢,實際上壓縮的效果是很有限的,如果資料大點XML格式壓縮出來的比二進位的還要大一些,二進位的壓縮出來居然比沒有壓縮大兩倍,也就是說壓縮比沒有壓縮還慘,而且相當的耗費時間。所以到底要不要對序列化的資料進行壓縮,最好還是實際測試一下再決定比較好。

創作者介紹
創作者 漠哥 的頭像
漠哥

人生四十宅開始 二號宅

漠哥 發表在 痞客邦 留言(0) 人氣()