把握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>