首页 > 开发 > 综合 > 正文

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

2024-07-21 02:29:17
字体:
来源:转载
供稿:网友

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

public class serializehelperclass serializehelper

    private sub new()sub new()
    end sub

    private shared function getxml()function getxml(byval obj as object) as 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()function getobj(byval objtype as type, byval xml as string) as 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()sub savexmlfile(byval filename as string, byval obj as object)
        dim xmlwriter as new system.io.streamwriter(filename, false)
        xmlwriter.write(getxml(obj))
        xmlwriter.close()
    end sub

    private shared function loadxmlfile()function loadxmlfile(byval filename as string, byval 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()sub saveserializerfile(byval filename as string, byval 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()function loaddeserializefile(byval filename as string, byval 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()function clone(byval obj as object) as 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()sub save(byval filename as string, byval 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()function load(byval filename as string, byval 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 formattypeenum formattype
        xml
        binary
        soap
    end enum
end class

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

public interface iconfiginformationinterface iconfiginformation
    property name()property name() as string
end interface

  name其实是字典键值。

  处理的基类:

public mustinherit class configinformationcollectionbaseclass 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()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()sub remove(byval name as string)
        if me.dictionary.contains(name) then me.dictionary.remove(name)
    end sub

    public readonly property items()property items() as tconfiginformation()
        get
            dim tmp(me.count - 1) as tconfiginformation
            me.dictionary.values.copyto(tmp, 0)
            return tmp
        end get
    end property

    public readonly property names()property names() as string()
        get
            dim tmp(me.count - 1) as string
            me.dictionary.keys.copyto(tmp, 0)
            return tmp
        end get
    end property

    public overloads sub clear()sub clear()
        me.dictionary.clear()
    end sub

    default public readonly property item()property item(byval name as string) as tconfiginformation
        get
            return ctype(me.dictionary.item(name), tconfiginformation)
        end get
    end property


    public sub save()sub save()
        dim mitems(me.count - 1) as tconfiginformation
        me.innerhashtable.values.copyto(mitems, 0)
        serializehelper.save(gfilename, gformattype, mitems)
    end sub

    private sub load()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()sub initialize()

    '默认为formattype.binary
    sub new()sub new()
        gfilename = string.format(gfilename, gettype(tconfiginformation).name)
        me.load()
    end sub

    sub new()sub new(byval formattype as serializehelper.formattype)
        gfilename = string.format(gfilename, gettype(tconfiginformation).name)
        gformattype = formattype
        me.load()
    end sub

    sub new()sub new(byval file as string, byval formattype as serializehelper.formattype)
        gfilename = file
        gformattype = formattype
        me.load()
    end sub

end class

  使用举例:

  1、定义配置或数据类

<serializable()> _
public class myconfiginfoclass myconfiginfo
    implements iconfiginformation

    private mmachine as string
    private mlogins(-1) as login

    public property machine()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()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 class
end class

  2、实现处理

public class configdataclass configdata
    inherits configinformationcollectionbase(of myconfiginfo)

    sub new()sub new()
        mybase.new()
    end sub
    sub new()sub new(byval formattype as serializehelper.formattype)
        mybase.new(formattype)
    end sub

    sub new()sub new(byval file as string, byval formattype as serializehelper.formattype)
        mybase.new(file, formattype)
    end sub

    '这是默认值,如果没有数据文件则生成文件并同时添加这些数据;若已存在文件,这里略去,不会处理。
    public overrides sub initialize()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()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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表