水如烟

                 顺其自然,水到渠成 LzmTW

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

导航

HOW TO:配置或数据文件的保存

Posted on 2006-04-09 14:40  水如烟(LzmTW)  阅读(462)  评论(0编辑  收藏  举报

Author:水如烟

配置类或数据类都需要可序列化。通常,序列化有三种方式,序列化和反序列化的过程可以做成一个静态类,如下:

Public Class SerializeHelper

    
Private Sub New()
    
End Sub


    
Private Shared Function GetXML(ByVal obj As ObjectAs String
        
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(obj.GetType)
        
Dim mStringWriter As New System.IO.StringWriter
        mSerializer.Serialize(mStringWriter, obj)
        
Return mStringWriter.ToString
    
End Function


    
Private Shared Function GetObj(ByVal objtype As Type, ByVal xml As StringAs Object
        
Dim mSerializer As New System.Xml.Serialization.XmlSerializer(objtype)
        
Dim mStringReader As New System.IO.StringReader(xml)
        
Return mSerializer.Deserialize(mStringReader)
    
End Function


    
Private Shared Sub SaveXmlFile(ByVal filename As StringByVal obj As Object)
        
Dim XmlWriter As New System.IO.StreamWriter(filename, False)
        XmlWriter.Write(GetXML(obj))
        XmlWriter.Close()
    
End Sub


    
Private Shared Function LoadXmlFile(ByVal filename As StringByVal objtype As Type) As Object
        
Dim XmlReader As New System.IO.StreamReader(filename, System.Text.Encoding.Default)
        
Dim mObj As Object
        mObj 
= GetObj(objtype, XmlReader.ReadToEnd)
        XmlReader.Close()
        
Return mObj
    
End Function


    
Private Shared Sub SaveSerializerFile(ByVal filename As StringByVal formatter As System.Runtime.Serialization.IFormatter, ByVal obj As Object)
        
Dim mFileStream As System.IO.Stream = System.IO.File.Open(filename, System.IO.FileMode.Create)
        formatter.Serialize(mFileStream, obj)
        mFileStream.Close()
    
End Sub


    
Private Shared Function LoadDeSerializeFile(ByVal FileName As StringByVal formatter As System.Runtime.Serialization.IFormatter) As Object
        
Dim mFileStream As System.IO.Stream = System.IO.File.Open(FileName, System.IO.FileMode.Open)
        
Dim mObj As Object
        mObj 
= formatter.Deserialize(mFileStream)
        mFileStream.Close()
        
Return mObj
    
End Function


    
Public Shared Function Clone(ByVal obj As ObjectAs Object
        
Dim mFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
        
Dim mMemoryStream As New System.IO.MemoryStream
        mFormatter.Serialize(mMemoryStream, obj)
        mMemoryStream.Position 
= 0
        
Return mFormatter.Deserialize(mMemoryStream)
    
End Function


    
Public Shared Sub Save(ByVal filename As StringByVal formattype As FormatType, ByVal obj As Object)
        
Select Case formattype
            
Case formattype.Binary
                SaveSerializerFile(filename, 
New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter, obj)
            
Case formattype.Soap
                SaveSerializerFile(filename, 
New System.Runtime.Serialization.Formatters.Soap.SoapFormatter, obj)
            
Case formattype.Xml
                SaveXmlFile(filename, obj)
        
End Select
    
End Sub


    
Public Shared Function Load(ByVal filename As StringByVal formattype As FormatType, ByVal XmlFormatObjType As Type) As Object
        
Select Case formattype
            
Case formattype.Binary
                
Return LoadDeSerializeFile(filename, New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter)
            
Case formattype.Soap
                
Return LoadDeSerializeFile(filename, New System.Runtime.Serialization.Formatters.Soap.SoapFormatter)
            
Case formattype.Xml
                
Return LoadXmlFile(filename, XmlFormatObjType)
        
End Select
        
Return Nothing
    
End Function



    
Public Enum FormatType
        Xml
        Binary
        Soap
    
End Enum

End Class


类的一个实例就是一项数据,如果有多个配置可选或者有多项数据,那就是一个数据集合了。在保存配置时,其实是将数据集合保存到文件里去。所以这里用集合的概念来处理。
为了使处理简单些,我引进一个接口,要求每个配置类或数据类必需实现这个接口。

Public Interface IConfigInformation
    
Property Name() As String
End Interface

NAME其实是字典键值。

处理的基类:


Public MustInherit Class ConfigInformationCollectionBase(Of TConfigInformation As IConfigInformation)
    
Inherits System.Collections.DictionaryBase

    
Private gformattype As SerializeHelper.FormatType = SerializeHelper.FormatType.Binary
    
Private gFileName As String = AppDomain.CurrentDomain.BaseDirectory & "{0}.dat" '{0}默认取类名,{1},文件后缀,这里默认都取为dat

    
Public Sub Add(ByVal item As TConfigInformation)
        
If Not Me.Dictionary.Contains(item.Name) Then Me.Dictionary.Add(item.Name, item)
    
End Sub


    
Public Sub Remove(ByVal Name As String)
        
If Me.Dictionary.Contains(Name) Then Me.Dictionary.Remove(Name)
    
End Sub


    
Public ReadOnly Property Items() As TConfigInformation()
        
Get
            
Dim tmp(Me.Count - 1As TConfigInformation
            
Me.Dictionary.Values.CopyTo(tmp, 0)
            
Return tmp
        
End Get
    
End Property


    
Public ReadOnly Property Names() As String()
        
Get
            
Dim tmp(Me.Count - 1As String
            
Me.Dictionary.Keys.CopyTo(tmp, 0)
            
Return tmp
        
End Get
    
End Property


    
Public Overloads Sub Clear()
        
Me.Dictionary.Clear()
    
End Sub


    
Default Public ReadOnly Property Item(ByVal Name As StringAs TConfigInformation
        
Get
            
Return CType(Me.Dictionary.Item(Name), TConfigInformation)
        
End Get
    
End Property



    
Public Sub Save()
        
Dim mItems(Me.Count - 1As TConfigInformation
        
Me.InnerHashtable.Values.CopyTo(mItems, 0)
        SerializeHelper.Save(gFileName, gformattype, mItems)
    
End Sub


    
Private Sub Load()
        
If Not IO.File.Exists(gFileName) Then
            Initialize()
            Save()
        
Else
            
Dim mItems() As TConfigInformation
            mItems 
= CType(SerializeHelper.Load(gFileName, gformattype, GetType(TConfigInformation)), TConfigInformation())
            
For Each item As TConfigInformation In mItems
                
Me.Add(item)
            
Next
        
End If
    
End Sub


    
'继承时,若有初始赋值,在此实现
    Public MustOverride Sub Initialize()

    
'默认为FormatType.Binary
    Sub New()
        gFileName 
= String.Format(gFileName, GetType(TConfigInformation).Name)
        
Me.Load()
    
End Sub


    
Sub New(ByVal formattype As SerializeHelper.FormatType)
        gFileName 
= String.Format(gFileName, GetType(TConfigInformation).Name)
        gformattype 
= formattype
        
Me.Load()
    
End Sub


    
Sub New(ByVal file As StringByVal formattype As SerializeHelper.FormatType)
        gFileName 
= file
        gformattype 
= formattype
        
Me.Load()
    
End Sub


End Class


使用举例:

1、定义配置或数据类

<Serializable()> _
Public Class MyConfigInfo
    
Implements IConfigInformation

    
Private mMachine As String
    
Private mLogins(-1As Login

    
Public Property Machine() As String Implements IConfigInformation.Name
        
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 MyConfigInfo)

    
Sub New()
        
MyBase.New()
    
End Sub

    
Sub New(ByVal formattype As SerializeHelper.FormatType)
        
MyBase.New(formattype)
    
End Sub


    
Sub New(ByVal file As StringByVal formattype As SerializeHelper.FormatType)
        
MyBase.New(file, formattype)
    
End Sub


    
'这是默认值,如果没有数据文件则生成文件并同时添加这些数据;若已存在文件,这里略去,不会处理。
    Public Overrides Sub Initialize()
        
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
        
Me.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
        
Me.Add(item)
    
End Sub

End Class

测试:

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        
Dim test As New ConfigData
        Console.WriteLine(test.Item(
"Fk-A01-03").Logins(0).User) 'L
        test.Item("Fk-A01-03").Logins(0).User = "Hello"
        test.Save() 
'存盘
        '用另一个打开,看看
        Dim test2 As New ConfigData
        Console.WriteLine(test2.Item(
"Fk-A01-03").Logins(0).User) 'Hello
    End Sub