把握 VB.NET 中的流 (Stream) ( 三 )
** 文件操作具体实例 ** ** **
在这一部分,你将找到更多常用的文件操作的代码实例。最常用、最基本的操作就是把 text 写入文件和读回来。现在的应用程序通常不用二进制文件作存储简单的变量,而用它来存储对象,对象集合以及其他机器代码。下面,将看到具体操作的例子。
** 读写文本文件 ** ** **
为了把 text 保存到文件,创建一个基于 FileStream 的 StreamReader 对象,然后调用 Write 方法把需要保存的 text 写入文件。下面的代码用 SaveFileDialog 提示用户指定一个文件,用于保存 TextBox1 的内容。
SaveFileDialog1.Filter = _
"Text Files|.txt|All Files|.*"
SaveFileDialog1.FilterIndex = 0
If SaveFileDialog1.ShowDialog = DialogResult.OK Then
Dim FS As FileStream = SaveFileDialog1.OpenFile
Dim SW As New StreamWriter(FS)
SW.Write(TextBox1.Text)
SW.Close()
FS.Close()
End If
同样采用类似的语句,我们读取一个文本文件,并把内容显示在 TextBox 控件中。 StreamReader 的 ReadToEnd 方法返回文件的全部内容。
OpenFileDialog1.Filter = _
"Text Files|.txt|All Files|.*"
OpenFileDialog1.FilterIndex = 0
If OpenFileDialog1.ShowDialog = DialogResult.OK Then
Dim FS As FileStream
FS = OpenFileDialog1.OpenFile
Dim SR As New StreamReader(FS)
TextBox1.Text = SR.ReadToEnd
SR.Close()
FS.Close()
End If
** 各种对象的存储 ** ** **
采用 BinaryFormatte 以二进制的形式,或者用 SoapFormatter 类以 XML 格式都可以序列化一个具体的对象。只要把所有 BinaryFormatter 的引用改为 SoapFormatter ,无需改变任何代码,就可以以 XML 格式序列化对象。
首先创建一个 BinaryFormatter 实例:
Dim BinFormatter As New Binary.BinaryFormatter()
然后创建一个用于存储序列化对象的 FileStream对象:
Dim FS As New System.IO.FileStream("c:\test.txt", IO.FileMode.Create)
接着调用 BinFormatter 的 _ Serialize _ 方法序列化任何可以序列化的 framework 对象:
R = New Rectangle(rnd.Next(0, 100),rnd.Next(0, 300), _
rnd.Next(10, 40),rnd.Next(1, 9))
BinFormatter.Serialize(FS, R)
加一个 Serializable 属性使得 自定义的对象可以序列化
1<serializable()> Public Structure Person
2
3Dim Name As String
4
5Dim Age As Integer
6
7Dim Income As Decimal
8
9End Structure
10
11下面代码创建一个 Person 对象实例,然后调用 BinFormatter的 _ Serialize _ 方法序列化自定义对象:
12
13P = New Person()
14
15P.Name = "Joe Doe"
16
17P.Age = 35
18
19P.Income = 28500
20
21BinFormatter.Serialize(FS, P)
22
23你也可以在同一个 Stream 中接着序列化其他对象,然后以同样的顺序读回。例如,在序列化 Person 对象之后接着序列化一个 Rectangle 对象:
24
25BinFormatter.Serialize(FS, New Rectangle(0, 0, 100, 200))
26
27创建一个 BinaryFormatter 对象,调用其 _ Deserialize _ 方法,然后把返回的值转化为正确的类型,就是整个反序列化过程。然后接着发序列化 Stream 的其他对象。
28
29假定已经序列化了 Person 和 Rectangle 两个对象,以同样的顺序,我们反序列化就可以得到原来的对象:
30
31
32
33_ _
34
35Dim P As New Person()
36
37P = BinFormatter.Serialize(FS, Person)
38
39Dim R As New Rectangle
40
41R = BinFormatter.Serialize(FS, Rectangle)
42
43** Persisting Collections **
44
45** 集合的存储 ** ** **
46
47大多数程序处理对象集合而不是单个的对象。对于集合数据,首先创建一个数组(或者是其他类型的集合,比如 ArrayList 或 HashTable ),用对象填充,然后一个 Serialize 方法就可以序列化真个集合,是不是很简单?下面的例子,首先创建一个有两个 Person 对象的 ArrayList ,然后序列化本身:
48
49
50
51Dim FS As New System.IO.FileStream _
52
53("c:\test.txt", IO.FileMode.Create)
54
55Dim BinFormatter As New Binary.BinaryFormatter()
56
57Dim P As New Person()
58
59Dim Persons As New ArrayList
60
61P = New Person()
62
63P.Name = "Person 1"
64
65P.Age = 35
66
67P.Income = 32000
68
69Persons.Add(P)
70
71P = New Person()
72
73P.Name = "Person 2"
74
75P.Age = 50
76
77P.Income = 72000
78
79Persons.Add(P)
80
81BinFormatter.Serialize(FS, Persons)
82
83以存储序列化数据的文件为参数, 调用一个 BinaryFormatter 实例的 _ Deserialize _ 方法,就会返回一个对象,然后把它转化为合适的类型。下面的代码反序列化文件中的所有对象,然后处理所有的 Person 对象:
84
85FS = New System.IO.FileStream _
86
87("c:\test.txt", IO.FileMode.OpenOrCreate)
88
89Dim obj As Object
90
91Dim P As Person(), R As Rectangle()
92
93Do
94
95obj = BinFormatter.Deserialize(FS)
96
97If obj.GetType Is GetType(Person) Then
98
99P = CType(obj, Person)
100
101' Process the P objext
102
103End If
104
105Loop While FS.Position < FS.Length - 1
106
107FS.Close()
108
109下面的例子调用 Deserialize 方法反序列化真个集合,然后把返回值转换为合适的类型( Person ):
110
111FS = New System.IO.FileStream("c:\test.txt", IO.FileMode.OpenOrCreate)
112
113Dim obj As Object
114
115Dim Persons As New ArrayList
116
117obj = CType(BinForm</serializable()>