Author:水如烟
HOW TO:配置或数据文件的保存 这个原是基于NET2003,其中又用了2005的泛型(OF TConfigInformation),显得不伦不类。现在改为2005的,并取消了接口的引入。
序列化类:
Public Class SerializeHelperClass SerializeHelper(Of T) Private Sub New()Sub New() End Sub <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Advanced)> _ Public Shared Function ItemToXml()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()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()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()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()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()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()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()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()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 FunctionEnd ClassPublic Enum FormatTypeEnum FormatType Xml Binary SoapEnd Enum配置与数据文件处理类:
Public MustInherit Class ConfigInformationCollectionBaseClass 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()Sub Read() Read(gformattype) End Sub Public Sub Read()Sub Read(ByVal formattype As LzmTW.FormatType) gFileName = String.Format(gFileName, GetType(TValue).Name) Read(gFileName, formattype) End Sub Public Sub Read()Sub Read(ByVal file As String, ByVal formattype As LzmTW.FormatType) gFileName = file gformattype = formattype Me.Load() End Sub Public Shadows Sub Add()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()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()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()Sub Initialize() ''' <summary> ''' 指定TValue的键名(字段或属性)的名称 ''' </summary> Protected MustOverride ReadOnly Property KeyName()Property KeyName() As String ''' <summary> ''' 指定TValue的键名是字段(真)还是属性(假) ''' </summary> Protected MustOverride ReadOnly Property KeyNameIsField()Property KeyNameIsField() As Boolean Sub New()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 MyConfigInfoClass MyConfigInfo Private mMachine As String Private mLogins(-1) As Login Public Property Machine()Property Machine() As String Get Return mMachine End Get Set(ByVal value As String) mMachine = value End Set End Property Public ReadOnly Property Logins()Property Logins() As Login() Get Return mLogins End Get End Property Public Sub Add()Sub Add(ByVal login As Login) ReDim Preserve mLogins(mLogins.Length) mLogins(mLogins.Length - 1) = login End Sub <Serializable()> _ Public Class LoginClass Login Private mUser As String Private mPass As String Public Property User()Property User() As String Get Return mUser End Get Set(ByVal value As String) mUser = value End Set End Property Public Property Pass()Property Pass() As String Get Return mPass End Get Set(ByVal value As String) mPass = value End Set End Property Sub New()Sub New() End Sub Sub New()Sub New(ByVal user As String, ByVal pass As String) Me.User = user Me.Pass = pass End Sub End ClassEnd Class2、实现处理
Public Class ConfigDataClass ConfigData Inherits ConfigInformationCollectionBase(Of String, MyConfigInfo) Protected Overrides Sub Initialize()Sub Initialize() End Sub Protected Overrides ReadOnly Property KeyName()Property KeyName() As String Get Return "Machine" End Get End Property Protected Overrides ReadOnly Property KeyNameIsField()Property KeyNameIsField() As Boolean Get Return False End Get End PropertyEnd Class测试:
Private Sub Button3_Click()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