.netで作成したアプリケーションのデータを永続的に保存するにはSystem.Runtime.Serialization.DataContractを使う。
クラスの復元に必要な属性をアノテーションで指定しておけば簡単に永続保存できる。
だが欠点がある。
シリアライズ・デシリアライズに使うJSONパーサが非常に遅いのだ。
少し大きなデータになると数十秒から数百秒のオーダーとなってしまうことはザラだ。
また参照オブジェクトの保存ができないので、いわゆるアドレス参照の属性を保存するには、それなりのロジック拡張が必要となる。
このあたりを解消する独自パーサを作ってみた。
ネイティブな型は以下の通り。
Byte,Char,Short,Integer,Long,Single,Double,String,Boolean,
Date,Enum,Array,List,Dictionary,
System.Drawing.Point,System.Drawing.Color
これ以外はDataContract指定のクラスでまかなう必要がある。
使い方はこんな感じになるだろうか。
Byson.BysonStorageがパーサで第一引数はマジックNo(ファイルを特定するためのLong番号)、第二引数はパーサがクラスを生成するために必要なアセンブリを渡している。
マジックNoはアプリケーション毎に違う番号にする必要がある。
IsMyFileはマジックNoによりファイルを識別している。
AnyObjectがDataContractにより定義されているクラスで、下記例ではひとつだが、ネイティブ型さえ使えば、あらゆるクラスがシリアライズ可能である。
認識可能と判断されたファイルからReadし、何らかの編集後、Writeにて永続化している。
<System.Runtime.Serialization.DataContract()> Public Class AnyObject <System.Runtime.Serialization.DataMember()> Private _data As String Public Sub New() End Sub Public ReadOnly Property Data As String Get Return Me._data End Get End Property End Class Public Class Mainclass Public Shared Sub Main() Dim storage As New Byson.BysonStorage( 123456789L, System.Reflection.Assembly.GetExecutingAssembly() ) Dim path As String = "c:hogedata.dat" If storage.IsMyFile(path) Then Dim anyobject = storage.Read(path) ' ' edit anyobject ... ' storage.Write(path, anyobject) Else MessageBox.Show("It is not my file !", "byson", MessageBoxButtons.OK, MessageBoxIcon.Warning) End If End Sub End Class
サンプル付きのプロジェクトを公開しますので、興味のある方は遊んでみてください。
サンプル付きプロジェクトはこちら