配置類或數據類都需要可序列化。通常,序列化有三種方式,序列化和反序列化的過程可以做成一個靜態類,如下:
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
新聞熱點
疑難解答