[Software Development] 關於序列化 (Serialization) 這件事

要是寫程式,一定多多少少會需要讀寫資料,畢竟 Program = Data Structure + Algorithm,只是大多數的情況下,資料的讀寫多半是對資料庫,而資料庫內的檔案實際讀寫由 DBMS 自己控制,開發人員基本上是碰不到的,但是資料不是只會存在資料庫內,像是檔案系統 (File System),網路資料或是其他可能的資料儲存地,而像這些不同的資料保存,都需要由開發人員自己處理 I/O 的工作...

只要是寫程式,一定多多少少會需要讀寫資料,畢竟 Program = Data Structure + Algorithm,只是大多數的情況下,資料的讀寫多半是對資料庫,而資料庫內的檔案實際讀寫由 DBMS 自己控制,開發人員基本上是碰不到的,但是資料不是只會存在資料庫內,像是檔案系統 (File System),網路資料或是其他可能的資料儲存地,而像這些不同的資料保存,都需要由開發人員自己處理 I/O 的工作,以檔案為例,.NET Framework 或是其他 Framework (ex: MFC) 都提供了很充份的檔案存取支援,例如 FileStream 或是 CArchive 等類別,可直接將資料寫入檔案,而不論是在哪個平台或系統,資料總是以資料流 (stream) 的概念模型來提供,就像網路的 socket 也是以資料流的方式來處理一樣。

對於物件導向的開發人員來說,物件是程式的根本,系統中總是充滿了各式各樣的物件,在操作物件的時候,有時會需要將資料儲存在檔案或透過網路傳遞,但是在物件和檔案中移動資料其實是很麻煩的事,首先,在程式讀入資料時,要以 iostream 或是 FileStream 將資料讀入,然後新增一個物件的執行個體,將資料塞到正確的屬性欄位中,最後再將完成的物件擲回給程式使用。這還只是做一個物件的時候,當做到多個物件時,還要再加上判斷資料是哪個物件所有,再動態生成物件並將資料塞給指定的屬性 (MFC 就是這樣做的),步驟十分的繁雜,所以才慢慢的出現序列化的系統服務出現,透過序列化,開發人員只要將型別與資料塞給序列化提供者,就能很快速的完成這件事。

以 .NET Framework 所提供的序列化服務來說,在 System.Runtime.Serialization.Formatters.Binary 命名空間中,提供了一個 BinaryFormatter,這是可將物件序列化成二進位的資料流,透過 Serialize() 與 Deserialize() 方法可以得到代表物件的二進位資料或由資料還原回物件。另外,還有 XML Serializer (System.Xml.Serialization 命名空間),可提供 XML/SOAP 與物件間的轉換工作,當然,也有很多第三方的物件序列化器 (ex: Json.NET 提供的 JsonSerializer),想實作自己的序列化器也可以,.NET Framework 雖然有 IFormatter 介面,不過沒有強制要求開發人員一定要實作,故基本上只要實作自己的 Serialize() 與 Deserialize() 即可,甚至可以直接將 MFC 的 CArchive 架構搬過來用。

不過我想要談的並不是序列化要怎麼做,而是序列化可以用在什麼地方。

最近經常看到一個問題,就是要怎麼把物件寫到 Cookies,或是將物件傳遞給另一個系統,讓另一個系統可以得到物件的資料.這個時候序列化就可以派上用場,例如將物件序列化給 Cookie,可以利用 Cookie 的 Name 設為物件的型別名稱或是組件名稱,而裡面的值可以放序列化後的值,當 Cookie 回傳給 server 時,則進行反序列化將資料還原給物件。透過網路傳輸也一樣,.NET Remoting 與 WCF 都應用了序列化來傳遞物件資料,但是透過網路傳輸的話,兩邊 (server, client) 都要有該型別的資訊,否則任何一方在處理序列化或反序列化時就會出問題。當然,以 Cookies 保存物件資料而言,server 和 client 都是同一支 Web application,所以比較沒這個問題。

序列化的實作重點是在物件如何轉換成指定的資料結構,像以二進位而言,物件型別要擺在前 8 bytes 或是用字串保留,然後後面跟著資料有多長,需不需要檢查碼或是有沒有額外的資料需要寫入 (ex: offset, flag, ...),這些規則都要被序列化與反序列化程式使用,藉以編碼或解碼資料

最後我要提的,序列化不是只有單純的資料格式轉換,其實不同的檔案內的資料結構是有很多藝術的,最簡單的例子就是 WORD 檔,你能想像一個 WORD 檔是怎麼塞進圖片,OLE 物件或是二進位資料的嗎?它內部其實是一個很大的 OLE Structured Storage 架構,哪些檔案該存哪裡,內部的指標,與主文件的對應等等,在一個 WORD 檔案中完全的實現。不只是 WORD 檔,像 Excel, PowerPoint 都有相似的結構,就連 PDF 檔案也有自己的檔案結構,所以序列化機制在充份的運用下,可以用來儲存高度複合的資料,連圖表或是照片也都可以和文件塞在同一個檔案中。熟悉序列化甚至寫一些簡單的序列化工具,對自己的物件永續存留的掌握一定會有很充份且直接的幫助。

Reference:

1. http://www.codeproject.com/KB/cs/MFC_Serialization.aspx

2. http://msdn.microsoft.com/en-us/library/7ay27kt9(v=vs.71).aspx