2010年12月23日 星期四

把握VB.NET中的流 Stream (2)

來源
---
把握VB.NET中的流(Stream) (二)

靈活多樣的IO操作
有時候,在數據和字節數組之間轉換是一件繁瑣的事情。為了避免這些無聊的轉換和簡化代碼,採用StreamReader/StreamWrite和BinaryReader/BinaryWriter不愧為明智之舉。StreamReader/StreamWrite分別由TextReader/TextWriter類派生,自動執行字節編碼的轉換。BinaryReader/BinaryWriter由Stream派生,主要以二進制的形式讀寫數據。
從二進制文件讀數據的時候,首先創建一個BinaryReader的實例,BinaryReader的構建函數接受一個FileStream對象,代表將要讀的文件。我們前面已經看過,可以用File.OpenRead 或者 File.OpenWrite 方法創建FileStream對象。
如下所示:
Dim BR As New IO.BinaryReader(IO.File.OpenRead(path))
Dim BW As New IO.BinaryWriter(IO.File.OpenWrite(path))
BinaryWriter類有Write和WriteLine兩種方法,都可以接受任何類型的數據作為參數寫入文件(WriteLine在文件尾追加一行數據)。BinaryReader類有很多讀數據的方法,數據存儲在文件上的時候,並沒有任何關於自己類型的信息,所以讀數據的時候,必須選擇合適的重載Read方法。
下面的例子假設BW是一個已經初始化過的BinaryWriter對象,表示如何寫一個字符串、整數、雙精度數字到文件:
BW.WriteLine("A String")
BW.WriteLine(12345)
BW.WriteLine(123.456789999999)
讀回數據的時候,必須選擇BinaryReader合適的Read方法:
Dim s As String = BR.ReadString()
Dim i As Int32 = BR.ReadInt32()
Dim dbl As Double = BR.ReadDouble()
對於文本文件,採用StreamReader/StreamWriter對象。方法跟上面差不多,寫數據同樣用Write和WriteLine方法。Read方法讀一個字符,ReadLine讀一行數據(直到有回車/換行符為止),ReadToEnd讀所有的字符,到文件結束。
對像序列化
到目前為止,我們只是把簡單類型的數據寫到文件中並讀回程序。而實際上,大多數的程序讀寫的數據可能並不是簡單類型,而是複雜的結構,例如:數組,數組列表,哈希表等。於是,我們採取一種成為序列化的技術,首先把數組的值轉化為字節序列,然後寫入文件,這樣整個數組就存儲下來。相反,我們稱之為反序列化。
序列化是.NET的一個很大的話題,這列介紹一下基本的信息。
用BinaryFormatter的Serialize 和 Deserialize方法把一個對像保存到文件和讀回程序。首先,imports System.RunTime.Serialization.Formatters,免得寫那麼長的申明。Formatters名空間包含了BinaryFormatter類,用於以二進制的數據序列化對象。
創建BinaryFormatter實例,接著調用Serialize方法,Serialize接受兩個參數:一個是可寫的FileStream實例,用於保存數據的文件;另外一個是對像本身:
Dim BinFormatter As New Binary.BinaryFormatter()
Dim R As New Rectangle(10, 20, 100, 200)
BinFormatter.Serialize(FS, R)
BinaryFormatter的Deserialize方法只有一個參數,FileStream實例。在當前位置,反序列化得到一個類型不明的對象,我們必須用Ctype轉換為原來的對象。下面的例子反序列化上面的文件得到原來的Rectangle對像:
Dim R As New Rectangle()
R = CType(BinFormatter.Deserialize(FS), Rectangle)
我們也可以以XmlFormatter進行對像序列化。首先在IDE的Project菜單選擇添加System.Runtime.Serialization.Formatters.Soap,然後就可以進行創建SoapFormatter對象了,方法跟BinFormatter一樣,只不過數據的存儲採用XML格式:
Dim FS As New IO.FileStream("c:\Rect.xml", IO.FileMode.Create, IO.FileAccess.Write)
Dim XMLFormatter As New SoapFormatter()
Dim R As New Rectangle(8, 8, 299, 499)
XMLFormatter.Serialize(FS, R)
打開c:\Rect.xml ,實際上裡面存儲了這些內容:
- <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
- <SOAP-ENV:Body>
- <a1:Rectangle id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/System.Drawing/System.Drawing%2C%20Version%3D1.0.3300.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db03f5f7f11d50a3a">
<x>8</x>
<y>8</y>
<width>249</width>
<height>499</height>
</a1:Rectangle>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

沒有留言:

張貼留言