Author:水如烟
HOW TO:配置或数据文件的保存 这个原是基于NET2003,其中又用了2005的泛型(OF TConfigInformation),显得不伦不类。现在改为2005的,并取消了接口的引入。
序列化类:
配置与数据文件处理类:
应用如下:
1、定义配置或数据类
2、实现处理
测试:
HOW TO:配置或数据文件的保存 这个原是基于NET2003,其中又用了2005的泛型(OF TConfigInformation),显得不伦不类。现在改为2005的,并取消了接口的引入。
序列化类:
Public Class SerializeHelper(Of T)
Private Sub New()
End Sub
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function ItemToXml(ByVal obj As T) As String
Dim mResult As String = ""
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim mStringWriter As New System.IO.StringWriter
Using mStringWriter
mSerializer.Serialize(mStringWriter, obj)
mResult = mStringWriter.ToString
mStringWriter.Close()
End Using
Return mResult
End Function
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function XmlToItem(ByVal xml As String) As T
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim mStringReader As New System.IO.StringReader(xml)
Return CType(mSerializer.Deserialize(mStringReader), T)
End Function
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Sub ItemToXmlFile(ByVal filename As String, ByVal obj As T)
Dim XmlWriter As New System.IO.StreamWriter(filename, False)
Using XmlWriter
XmlWriter.Write(ItemToXml(obj))
XmlWriter.Close()
End Using
End Sub
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function XmlFileToItem(ByVal filename As String) As T
Dim XmlReader As New System.IO.StreamReader(filename, System.Text.Encoding.Default)
Dim mObj As T
Using XmlReader
mObj = XmlToItem(XmlReader.ReadToEnd)
XmlReader.Close()
End Using
Return mObj
End Function
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Sub ItemToFormatterFile(ByVal filename As String, ByVal formatter As System.Runtime.Serialization.IFormatter, ByVal obj As T)
Dim mFileStream As System.IO.Stream = System.IO.File.Open(filename, System.IO.FileMode.Create)
Using mFileStream
formatter.Serialize(mFileStream, obj)
mFileStream.Close()
End Using
End Sub
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function FormatterFileToItem(ByVal FileName As String, ByVal formatter As System.Runtime.Serialization.IFormatter) As T
Dim mFileStream As System.IO.Stream = System.IO.File.Open(FileName, System.IO.FileMode.Open)
Dim mObj As T
Using mFileStream
mObj = CType(formatter.Deserialize(mFileStream), T)
mFileStream.Close()
End Using
Return mObj
End Function
Public Shared Function Clone(ByVal obj As T) As T
Dim tmpT As T
Dim mFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim mMemoryStream As New System.IO.MemoryStream
Using mMemoryStream
mFormatter.Serialize(mMemoryStream, obj)
mMemoryStream.Position = 0
tmpT = CType(mFormatter.Deserialize(mMemoryStream), T)
mMemoryStream.Close()
End Using
Return tmpT
End Function
Public Shared Sub Save(ByVal filename As String, ByVal formattype As FormatType, ByVal obj As T)
Select Case formattype
Case formattype.Binary
ItemToFormatterFile(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter, obj)
Case formattype.Soap
ItemToFormatterFile(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter, obj)
Case formattype.Xml
ItemToXmlFile(filename, obj)
End Select
End Sub
Public Shared Function Load(ByVal filename As String, ByVal formattype As FormatType) As T
Select Case formattype
Case formattype.Binary
Return FormatterFileToItem(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter)
Case formattype.Soap
Return FormatterFileToItem(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter)
Case formattype.Xml
Return XmlFileToItem(filename)
End Select
Return Nothing
End Function
End Class
Public Enum FormatType
Xml
Binary
Soap
End Enum
Private Sub New()
End Sub
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function ItemToXml(ByVal obj As T) As String
Dim mResult As String = ""
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim mStringWriter As New System.IO.StringWriter
Using mStringWriter
mSerializer.Serialize(mStringWriter, obj)
mResult = mStringWriter.ToString
mStringWriter.Close()
End Using
Return mResult
End Function
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function XmlToItem(ByVal xml As String) As T
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim mStringReader As New System.IO.StringReader(xml)
Return CType(mSerializer.Deserialize(mStringReader), T)
End Function
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Sub ItemToXmlFile(ByVal filename As String, ByVal obj As T)
Dim XmlWriter As New System.IO.StreamWriter(filename, False)
Using XmlWriter
XmlWriter.Write(ItemToXml(obj))
XmlWriter.Close()
End Using
End Sub
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function XmlFileToItem(ByVal filename As String) As T
Dim XmlReader As New System.IO.StreamReader(filename, System.Text.Encoding.Default)
Dim mObj As T
Using XmlReader
mObj = XmlToItem(XmlReader.ReadToEnd)
XmlReader.Close()
End Using
Return mObj
End Function
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Sub ItemToFormatterFile(ByVal filename As String, ByVal formatter As System.Runtime.Serialization.IFormatter, ByVal obj As T)
Dim mFileStream As System.IO.Stream = System.IO.File.Open(filename, System.IO.FileMode.Create)
Using mFileStream
formatter.Serialize(mFileStream, obj)
mFileStream.Close()
End Using
End Sub
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _
Public Shared Function FormatterFileToItem(ByVal FileName As String, ByVal formatter As System.Runtime.Serialization.IFormatter) As T
Dim mFileStream As System.IO.Stream = System.IO.File.Open(FileName, System.IO.FileMode.Open)
Dim mObj As T
Using mFileStream
mObj = CType(formatter.Deserialize(mFileStream), T)
mFileStream.Close()
End Using
Return mObj
End Function
Public Shared Function Clone(ByVal obj As T) As T
Dim tmpT As T
Dim mFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim mMemoryStream As New System.IO.MemoryStream
Using mMemoryStream
mFormatter.Serialize(mMemoryStream, obj)
mMemoryStream.Position = 0
tmpT = CType(mFormatter.Deserialize(mMemoryStream), T)
mMemoryStream.Close()
End Using
Return tmpT
End Function
Public Shared Sub Save(ByVal filename As String, ByVal formattype As FormatType, ByVal obj As T)
Select Case formattype
Case formattype.Binary
ItemToFormatterFile(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter, obj)
Case formattype.Soap
ItemToFormatterFile(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter, obj)
Case formattype.Xml
ItemToXmlFile(filename, obj)
End Select
End Sub
Public Shared Function Load(ByVal filename As String, ByVal formattype As FormatType) As T
Select Case formattype
Case formattype.Binary
Return FormatterFileToItem(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter)
Case formattype.Soap
Return FormatterFileToItem(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter)
Case formattype.Xml
Return XmlFileToItem(filename)
End Select
Return Nothing
End Function
End Class
Public Enum FormatType
Xml
Binary
Soap
End Enum
配置与数据文件处理类:
Public MustInherit Class ConfigInformationCollectionBase(Of TKey, TValue)
Inherits System.Collections.Generic.Dictionary(Of TKey, TValue)
'默认为FormatType.Binary
Private gformattype As LzmTW.FormatType = LzmTW.FormatType.Binary
Private gFileName As String = AppDomain.CurrentDomain.BaseDirectory & "{0}.dat"
Public Sub Read()
Read(gformattype)
End Sub
Public Sub Read(ByVal formattype As LzmTW.FormatType)
gFileName = String.Format(gFileName, GetType(TValue).Name)
Read(gFileName, formattype)
End Sub
Public Sub Read(ByVal file As String, ByVal formattype As LzmTW.FormatType)
gFileName = file
gformattype = formattype
Me.Load()
End Sub
Public Shadows Sub Add(ByVal item As TValue)
Dim mKeyValue As TKey = Nothing
If KeyNameIsField() Then
mKeyValue = CType(GetType(TValue).GetField(KeyName).GetValue(item), TKey)
Else
mKeyValue = CType(GetType(TValue).GetProperty(KeyName).GetValue(item, Nothing), TKey)
End If
If Not Me.ContainsKey(mKeyValue) Then
'不存在,增加记录
MyBase.Add(mKeyValue, item)
Else
'存在,作修改处理
Me.Item(mKeyValue) = item
End If
End Sub
Public Sub Save()
Dim mItems(Me.Count - 1) As TValue
Me.Values.CopyTo(mItems, 0)
SerializeHelper(Of TValue()).Save(gFileName, gformattype, mItems)
End Sub
Private Sub Load()
If Not IO.File.Exists(gFileName) Then
Initialize()
Save()
Else
Dim mItems() As TValue
mItems = CType(SerializeHelper(Of TValue()).Load(gFileName, gformattype), TValue())
For Each item As TValue In mItems
Me.Add(item)
Next
End If
End Sub
''' <summary>
''' '继承时,若有初始赋值,在此实现
''' </summary>
Protected MustOverride Sub Initialize()
''' <summary>
''' 指定TValue的键名(字段或属性)的名称
''' </summary>
Protected MustOverride ReadOnly Property KeyName() As String
''' <summary>
''' 指定TValue的键名是字段(真)还是属性(假)
''' </summary>
Protected MustOverride ReadOnly Property KeyNameIsField() As Boolean
Sub New()
'检测键名是否有效,键名的类和TKey是否相符
If KeyNameIsField() Then
Dim mFieldInfo As Reflection.FieldInfo = GetType(TValue).GetField(KeyName)
If mFieldInfo Is Nothing Then
Throw New SystemException(String.Format("类{0}中不存在名称为{1}的字段", GetType(TValue).Name, KeyName))
Else
If Not mFieldInfo.FieldType.Name.Equals(GetType(TKey).Name) Then
Throw New SystemException(String.Format("类{0}中字段名称为{1}的类型为{2},与指定的键值类型{3}不符", GetType(TValue).Name, KeyName, mFieldInfo.FieldType.Name, GetType(TKey).Name))
End If
End If
Else
Dim mPropertyInfo As Reflection.PropertyInfo = GetType(TValue).GetProperty(KeyName)
If mPropertyInfo Is Nothing Then
Throw New SystemException(String.Format("类{0}中不存在名称为{1}的属性", GetType(TValue).Name, KeyName))
Else
If Not mPropertyInfo.PropertyType.Name.Equals(GetType(TKey).Name) Then
Throw New SystemException(String.Format("类{0}中属性名称为{1}的类型为{2},与指定的键值类型{3}不符", GetType(TValue).Name, KeyName, mPropertyInfo.PropertyType.Name, GetType(TKey).Name))
End If
End If
End If
End Sub
End Class
Inherits System.Collections.Generic.Dictionary(Of TKey, TValue)
'默认为FormatType.Binary
Private gformattype As LzmTW.FormatType = LzmTW.FormatType.Binary
Private gFileName As String = AppDomain.CurrentDomain.BaseDirectory & "{0}.dat"
Public Sub Read()
Read(gformattype)
End Sub
Public Sub Read(ByVal formattype As LzmTW.FormatType)
gFileName = String.Format(gFileName, GetType(TValue).Name)
Read(gFileName, formattype)
End Sub
Public Sub Read(ByVal file As String, ByVal formattype As LzmTW.FormatType)
gFileName = file
gformattype = formattype
Me.Load()
End Sub
Public Shadows Sub Add(ByVal item As TValue)
Dim mKeyValue As TKey = Nothing
If KeyNameIsField() Then
mKeyValue = CType(GetType(TValue).GetField(KeyName).GetValue(item), TKey)
Else
mKeyValue = CType(GetType(TValue).GetProperty(KeyName).GetValue(item, Nothing), TKey)
End If
If Not Me.ContainsKey(mKeyValue) Then
'不存在,增加记录
MyBase.Add(mKeyValue, item)
Else
'存在,作修改处理
Me.Item(mKeyValue) = item
End If
End Sub
Public Sub Save()
Dim mItems(Me.Count - 1) As TValue
Me.Values.CopyTo(mItems, 0)
SerializeHelper(Of TValue()).Save(gFileName, gformattype, mItems)
End Sub
Private Sub Load()
If Not IO.File.Exists(gFileName) Then
Initialize()
Save()
Else
Dim mItems() As TValue
mItems = CType(SerializeHelper(Of TValue()).Load(gFileName, gformattype), TValue())
For Each item As TValue In mItems
Me.Add(item)
Next
End If
End Sub
''' <summary>
''' '继承时,若有初始赋值,在此实现
''' </summary>
Protected MustOverride Sub Initialize()
''' <summary>
''' 指定TValue的键名(字段或属性)的名称
''' </summary>
Protected MustOverride ReadOnly Property KeyName() As String
''' <summary>
''' 指定TValue的键名是字段(真)还是属性(假)
''' </summary>
Protected MustOverride ReadOnly Property KeyNameIsField() As Boolean
Sub New()
'检测键名是否有效,键名的类和TKey是否相符
If KeyNameIsField() Then
Dim mFieldInfo As Reflection.FieldInfo = GetType(TValue).GetField(KeyName)
If mFieldInfo Is Nothing Then
Throw New SystemException(String.Format("类{0}中不存在名称为{1}的字段", GetType(TValue).Name, KeyName))
Else
If Not mFieldInfo.FieldType.Name.Equals(GetType(TKey).Name) Then
Throw New SystemException(String.Format("类{0}中字段名称为{1}的类型为{2},与指定的键值类型{3}不符", GetType(TValue).Name, KeyName, mFieldInfo.FieldType.Name, GetType(TKey).Name))
End If
End If
Else
Dim mPropertyInfo As Reflection.PropertyInfo = GetType(TValue).GetProperty(KeyName)
If mPropertyInfo Is Nothing Then
Throw New SystemException(String.Format("类{0}中不存在名称为{1}的属性", GetType(TValue).Name, KeyName))
Else
If Not mPropertyInfo.PropertyType.Name.Equals(GetType(TKey).Name) Then
Throw New SystemException(String.Format("类{0}中属性名称为{1}的类型为{2},与指定的键值类型{3}不符", GetType(TValue).Name, KeyName, mPropertyInfo.PropertyType.Name, GetType(TKey).Name))
End If
End If
End If
End Sub
End Class
应用如下:
1、定义配置或数据类
<Serializable()> _
Public Class MyConfigInfo
Private mMachine As String
Private mLogins(-1) As Login
Public Property Machine() As String
Get
Return mMachine
End Get
Set(ByVal value As String)
mMachine = value
End Set
End Property
Public ReadOnly Property Logins() As Login()
Get
Return mLogins
End Get
End Property
Public Sub Add(ByVal login As Login)
ReDim Preserve mLogins(mLogins.Length)
mLogins(mLogins.Length - 1) = login
End Sub
<Serializable()> _
Public Class Login
Private mUser As String
Private mPass As String
Public Property User() As String
Get
Return mUser
End Get
Set(ByVal value As String)
mUser = value
End Set
End Property
Public Property Pass() As String
Get
Return mPass
End Get
Set(ByVal value As String)
mPass = value
End Set
End Property
Sub New()
End Sub
Sub New(ByVal user As String, ByVal pass As String)
Me.User = user
Me.Pass = pass
End Sub
End Class
End Class
Public Class MyConfigInfo
Private mMachine As String
Private mLogins(-1) As Login
Public Property Machine() As String
Get
Return mMachine
End Get
Set(ByVal value As String)
mMachine = value
End Set
End Property
Public ReadOnly Property Logins() As Login()
Get
Return mLogins
End Get
End Property
Public Sub Add(ByVal login As Login)
ReDim Preserve mLogins(mLogins.Length)
mLogins(mLogins.Length - 1) = login
End Sub
<Serializable()> _
Public Class Login
Private mUser As String
Private mPass As String
Public Property User() As String
Get
Return mUser
End Get
Set(ByVal value As String)
mUser = value
End Set
End Property
Public Property Pass() As String
Get
Return mPass
End Get
Set(ByVal value As String)
mPass = value
End Set
End Property
Sub New()
End Sub
Sub New(ByVal user As String, ByVal pass As String)
Me.User = user
Me.Pass = pass
End Sub
End Class
End Class
2、实现处理
Public Class ConfigData
Inherits ConfigInformationCollectionBase(Of String, MyConfigInfo)
Protected Overrides Sub Initialize()
End Sub
Protected Overrides ReadOnly Property KeyName() As String
Get
Return "Machine"
End Get
End Property
Protected Overrides ReadOnly Property KeyNameIsField() As Boolean
Get
Return False
End Get
End Property
End Class
Inherits ConfigInformationCollectionBase(Of String, MyConfigInfo)
Protected Overrides Sub Initialize()
End Sub
Protected Overrides ReadOnly Property KeyName() As String
Get
Return "Machine"
End Get
End Property
Protected Overrides ReadOnly Property KeyNameIsField() As Boolean
Get
Return False
End Get
End Property
End Class
测试:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim test As New ConfigData
'读文件
test.Read()
Dim item As MyConfigInfo
item = New MyConfigInfo
With item
.Machine = "Fk-A01-02"
.Add(New MyConfigInfo.Login("LzmTW", "001"))
.Add(New MyConfigInfo.Login("Lzm", "002"))
End With
test.Add(item)
item = New MyConfigInfo
With item
.Machine = "Fk-A01-03"
.Add(New MyConfigInfo.Login("L", "003"))
.Add(New MyConfigInfo.Login("Lz", "004"))
.Add(New MyConfigInfo.Login("LzmTW", "001"))
End With
test.Add(item)
Console.WriteLine(test.Item("Fk-A01-03").Logins(0).User)
test.Item("Fk-A01-03").Logins(0).User = "Hello"
test.Save() '存盘
'用另一个打开,看看
Dim test2 As New ConfigData
test2.Read()
Console.WriteLine(test2.Item("Fk-A01-03").Logins(0).User)
End Sub
Dim test As New ConfigData
'读文件
test.Read()
Dim item As MyConfigInfo
item = New MyConfigInfo
With item
.Machine = "Fk-A01-02"
.Add(New MyConfigInfo.Login("LzmTW", "001"))
.Add(New MyConfigInfo.Login("Lzm", "002"))
End With
test.Add(item)
item = New MyConfigInfo
With item
.Machine = "Fk-A01-03"
.Add(New MyConfigInfo.Login("L", "003"))
.Add(New MyConfigInfo.Login("Lz", "004"))
.Add(New MyConfigInfo.Login("LzmTW", "001"))
End With
test.Add(item)
Console.WriteLine(test.Item("Fk-A01-03").Logins(0).User)
test.Item("Fk-A01-03").Logins(0).User = "Hello"
test.Save() '存盘
'用另一个打开,看看
Dim test2 As New ConfigData
test2.Read()
Console.WriteLine(test2.Item("Fk-A01-03").Logins(0).User)
End Sub