オブジェクトの内容をバイナリファイルに保存する簡単な方法として、BinaryFormatterクラスを使う方法が挙げられます。BinaryFormatterを使用してオブジェクトをシリアル化し、FileStreamでファイルに書き込むのです。
補足:BinaryFormatterクラスの代わりにSoapFormatterクラスを使って、XMLファイルに保存することもできます。SoapFormatterの使い方は、ここで紹介している方法とほぼ同じです。
ここでは次のようなTestClassクラスがあるものとし、BinaryFormatterクラスを使ってTestClassオブジェクトをバイナリファイルに保存する方法を紹介します。
Public Class TestClass Private _message As String Private _number As Integer Public Property Message() As String Get Return _message End Get Set(ByVal Value As String) _message = value End Set End Property Public Property Number() As Integer Get Return _number End Get Set(ByVal Value As Integer) _number = value End Set End Property Public Sub New(ByVal str As String, ByVal num As Integer) _message = str _number = num End Sub End Class
public class TestClass { private string _message; private int _number; public string Message { get {return _message;} set {_message = value;} } public int Number { get {return _number;} set {_number = value;} } public TestClass(string str, int num) { _message = str; _number = num; } }
まず次のようにTestClassクラスにSerializableAttribute属性を付加する必要があります。
<Serializable()> _ Public Class TestClass '(省略) End Class
[Serializable()] public class TestClass { //(省略) }
TestClassオブジェクトを保存、復元する具体的なコードを以下に示します。SaveToBinaryFileメソッドでオブジェクトを保存し、LoadFromBinaryFileメソッドでオブジェクトの復元ができます。
Imports System Imports System.IO Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary Public Class MainClass Public Shared Sub Main() '保存先のファイル名 Dim fileName As String = "C:\test.obj" 'TestClassオブジェクトを作成 Dim obj1 As New TestClass("テストです。", 123) 'オブジェクトの内容をファイルに保存する SaveToBinaryFile(obj1, fileName) 'オブジェクトの内容をファイルから読み込み復元する Dim obj2 As TestClass = CType(LoadFromBinaryFile(fileName), TestClass) '読み込んだオブジェクトの内容を表示 Console.WriteLine(obj2.Message) Console.WriteLine(obj2.Number) Console.ReadLine() End Sub ''' <summary> ''' オブジェクトの内容をファイルから読み込み復元する ''' </summary> ''' <param name="path">読み込むファイル名</param> ''' <returns>復元されたオブジェクト</returns> Public Shared Function LoadFromBinaryFile(ByVal path As String) As Object Dim fs As New FileStream(path, FileMode.Open, FileAccess.Read) Dim f As New BinaryFormatter '読み込んで逆シリアル化する Dim obj As Object = f.Deserialize(fs) fs.Close() Return obj End Function ''' <summary> ''' オブジェクトの内容をファイルに保存する ''' </summary> ''' <param name="obj">保存するオブジェクト</param> ''' <param name="path">保存先のファイル名</param> Public Shared Sub SaveToBinaryFile( _ ByVal obj As Object, ByVal path As String) Dim fs As New FileStream( _ path, FileMode.Create, FileAccess.Write) Dim bf As New BinaryFormatter 'シリアル化して書き込む bf.Serialize(fs, obj) fs.Close() End Sub End Class
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; public class MainClass { public static void Main() { //保存先のファイル名 string fileName = "C:\\test.obj"; //TestClassオブジェクトを作成 TestClass obj1 = new TestClass("テストです。", 123); //オブジェクトの内容をファイルに保存する SaveToBinaryFile(obj1, fileName); //オブジェクトの内容をファイルから読み込み復元する TestClass obj2 = (TestClass) LoadFromBinaryFile(fileName); //読み込んだオブジェクトの内容を表示 Console.WriteLine(obj2.Message); Console.WriteLine(obj2.Number); Console.ReadLine(); } /// <summary> /// オブジェクトの内容をファイルから読み込み復元する /// </summary> /// <param name="path">読み込むファイル名</param> /// <returns>復元されたオブジェクト</returns> public static object LoadFromBinaryFile(string path) { FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); BinaryFormatter f = new BinaryFormatter(); //読み込んで逆シリアル化する object obj = f.Deserialize(fs); fs.Close(); return obj; } /// <summary> /// オブジェクトの内容をファイルに保存する /// </summary> /// <param name="obj">保存するオブジェクト</param> /// <param name="path">保存先のファイル名</param> public static void SaveToBinaryFile(object obj, string path) { FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); BinaryFormatter bf = new BinaryFormatter(); //シリアル化して書き込む bf.Serialize(fs, obj); fs.Close(); } }
上記のようにBinaryFormatterを使用してオブジェクトを保存した場合、保存されるのはクラスのフィールドで、パブリックフィールドはもちろん、プライベートフィールドも保存されます。保存したくないフィールドにはNonSerializedAttribute属性を付けます。
次の例では、TestClassクラスの_numberフィールドをシリアル化の対象からはずし、保存されないようにしています。
<Serializable()> _ Public Class TestClass <NonSerialized()> _ Private _message As String '(省略) End Class
[Serializable()] public class TestClass { private string _message; [NonSerialized()] private int _number; //(省略) }
注意:「マイクロソフト サポート技術情報 - 320079」では「BUG: BinaryFormatter と .NET リモートが深いネスト Structs を deserialize することができません。」というバグが紹介されていますので、構造体のシリアル化でBinaryFormatterを使う場合は注意が必要です。