水如烟

                 顺其自然,水到渠成 LzmTW

文或代码皆是面向初学者.我是爱好者,也是初学者.那些"文章",只按自己理解写,我是不知术语名词的.所以只供参考,也仅供参考.

导航

HOW TO:配置或数据文件的保存(改进)

Posted on 2006-04-10 13:01  水如烟(LzmTW)  阅读(391)  评论(0编辑  收藏  举报
Author:水如烟

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 StringAs 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 StringByVal 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 StringAs 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 StringByVal 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 StringByVal 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 StringByVal 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 StringByVal 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 StringByVal 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 - 1As 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(-1As 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 StringByVal 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

测试:
    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