DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DOBON.NET

オブジェクトの内容をファイルに保存、復元する

オブジェクトのXMLシリアル化、逆シリアル化を行う

.NET Frameworkには、オブジェクトの内容をファイルに保存し、また復元することを簡単に実現する機能が用意されています。XmlSerializerクラスのSerializeメソッドを使ってオブジェクトをシリアル化(シリアライズ)してXMLファイルに保存し、XmlSerializerクラスのDeserializeメソッドを使ってXMLファイルをオブジェクトに逆シリアル化(デシリアライズ)します。INIファイルの代わりとして、設定を保存、復元したい時などにも有用な機能です。

オブジェクトの内容をXMLファイルに保存する

次のコードでは、SampleClassオブジェクトの内容をXMLファイル(C:\test.xml)に保存しています。

[VB.NET]
'XMLファイルに保存するオブジェクトのためのクラス
Public Class SampleClass
    Public Number As Integer
    Public Message As String
End Class

Class MainClass
    'エントリポイント
    Public Shared Sub Main()
        '保存先のファイル名
        Dim fileName As String = "C:\test.xml"
        '保存するクラス(SampleClass)のインスタンスを作成
        Dim cls As New SampleClass
        cls.Message = "テストです。"
        cls.Number = 123

        'XmlSerializerオブジェクトを作成
        '書き込むオブジェクトの型を指定する
        Dim serializer As _
            New System.Xml.Serialization.XmlSerializer( _
                GetType(SampleClass))
        'ファイルを開く
        Dim fs As New System.IO.FileStream( _
            fileName, System.IO.FileMode.Create)
        'シリアル化し、XMLファイルに保存する
        serializer.Serialize(fs, cls)
        '閉じる
        fs.Close()
    End Sub
End Class
[C#]
//XMLファイルに保存するオブジェクトのためのクラス
public class SampleClass
{
    public int Number;
    public string Message;
}

class MainClass
{
    //エントリポイント
    public static void Main()
    {
        //保存先のファイル名
        string fileName = @"C:\test.xml";
        //保存するクラス(SampleClass)のインスタンスを作成
        SampleClass cls = new SampleClass();
        cls.Message = "テストです。";
        cls.Number = 123;

        //XmlSerializerオブジェクトを作成
        //書き込むオブジェクトの型を指定する
        System.Xml.Serialization.XmlSerializer serializer =
            new System.Xml.Serialization.XmlSerializer(
                typeof(SampleClass));
        //ファイルを開く
        System.IO.FileStream fs =
            new System.IO.FileStream(fileName,
                System.IO.FileMode.Create);
        //シリアル化し、XMLファイルに保存する
        serializer.Serialize(fs, cls);
        //閉じる
        fs.Close();
    }
}

FileStreamクラスによりファイルを読み書きする方法の詳細は、こちらをご覧ください。

上記の例により作成されたXMLファイルの内容は、次のようになります(文字コードUTF-8で書き込まれます)。

この方法によりXMLファイルに書き込まれる要素は、パブリックメンバであるフィールドとプロパティだけです。さらに、読み込み、あるいは書き込みしか許可されていないプロパティは、パブリックメンバであっても書き込まれません。また、シリアル化するオブジェクトのクラスには、規定のコンストラクタ(引数を持たないコンストラクタ)が必要です。

XMLファイルの内容をオブジェクトに復元する

次に、上記のコードにより保存されたXMLファイルから、SampleClassオブジェクトの内容を復元するコードを示します。

[VB.NET]
'XMLファイルに保存するオブジェクトのためのクラス
Public Class SampleClass
    Public Number As Integer
    Public Message As String
End Class

Class MainClass
    'エントリポイント
    Public Shared Sub Main()
        '保存元のファイル名
        Dim fileName As String = "C:\test.xml"

        'XmlSerializerオブジェクトの作成
        Dim serializer As _
            New System.Xml.Serialization.XmlSerializer( _
                GetType(SampleClass))
        'ファイルを開く
        Dim fs As New System.IO.FileStream( _
            fileName, System.IO.FileMode.Open)
        'XMLファイルから読み込み、逆シリアル化する
        Dim cls As SampleClass = _
            CType(serializer.Deserialize(fs), SampleClass)
        '閉じる
        fs.Close()
    End Sub
End Class
[C#]
//XMLファイルに保存するオブジェクトのためのクラス
public class SampleClass
{
    public int Number;
    public string Message;
}

class MainClass
{
    //エントリポイント
    public static void Main()
    {
        //保存元のファイル名
        string fileName = @"C:\test.xml";

        //XmlSerializerオブジェクトの作成
        System.Xml.Serialization.XmlSerializer serializer =
            new System.Xml.Serialization.XmlSerializer(
                typeof(SampleClass));
        //ファイルを開く
        System.IO.FileStream fs =
            new System.IO.FileStream(fileName,
                System.IO.FileMode.Open);
        //XMLファイルから読み込み、逆シリアル化する
        SampleClass cls =
            (SampleClass) serializer.Deserialize(fs);
        //閉じる
        fs.Close();
    }
}

XMLファイルに書き込まないメンバを指定する

パブリックメンバであってもXMLファイルに書き込みたくないケースも考えられます。このような時は、書き込みたくないメンバにXmlIgnoreAttribute属性をつけます。先のSampleClassクラスを次のように書き換えることにより、SampleClassオブジェクトのMessageフィールドの値がXMLファイルに書き込まれなくなります。

[VB.NET]
'XMLファイルに保存するオブジェクトのためのクラス
Public Class SampleClass
    Public Number As Integer
    'このメンバの値はシリアル化しないようにする
    <System.Xml.Serialization.XmlIgnoreAttribute()> _
    Public Message As String
End Class
[C#]
//XMLファイルに保存するオブジェクトのためのクラス
public class SampleClass
{
    public int Number;
    //このメンバの値はシリアル化しないようにする
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public string Message;
}

要素名を変更する

今までの例では、クラスの名前(SampleClass)とメンバの名前(NumberとMessage)がそのままXMLファイルの要素名に利用されていました。しかし、この要素名を別の名前に変えたいケースもあるでしょう。そのような時は、XmlRoot及びXmlElementを指定します。

先のSampleClassクラスを次のように書き換え、"SampleClass"の代わりに"サンプル"、"Number"と"Message"の代わりに"数字"と"文字列"と、XMLファイルに出力するようにしています。

[VB.NET]
'XMLファイルに保存するオブジェクトのためのクラス
<System.Xml.Serialization.XmlRoot("サンプル")> _
Public Class SampleClass
    <System.Xml.Serialization.XmlElement("数字")> _
    Public Number As Integer
    <System.Xml.Serialization.XmlElement("文字列")> _
    Public Message As String
End Class
[C#]
//XMLファイルに保存するオブジェクトのためのクラス
[System.Xml.Serialization.XmlRoot("サンプル")]
public class SampleClass
{
    [System.Xml.Serialization.XmlElement("数字")]
    public int Number;
    [System.Xml.Serialization.XmlElement("文字列")]
    public string Message;
}

出力されるXMLファイルの内容は次のようになります。

配列のシリアル化、逆シリアル化

最後に蛇足となりますが、SampleClassオブジェクトの配列の内容をXMLに保存し、さらに復元しする例を紹介します。今まで紹介した方法と何も変わりません。

[VB.NET]
'次のクラスが宣言されているものとする
'Public Class SampleClass
'        Public Number As Integer
'        Public Message As String
'End Class

'保存するオブジェクトの配列を作成
Dim myClasses(9) As SampleClass
Dim i As Integer
For i = 0 To 9
    myClasses(i) = New SampleClass
    myClasses(i).Number = i
    myClasses(i).Message = i.ToString() + "だよ。"
Next

'XMLファイルに保存
Dim serializer1 As _
    New System.Xml.Serialization.XmlSerializer( _
        GetType(SampleClass()))
Dim fs1 As New IO.FileStream( _
    "C:\test.xml", IO.FileMode.Create)
serializer1.Serialize(fs1, myClasses)
fs1.Close()

'保存した内容を復元
Dim serializer2 As _
    New System.Xml.Serialization.XmlSerializer( _
        GetType(SampleClass()))
Dim fs2 As New IO.FileStream( _
    "C:\test.xml", IO.FileMode.Open)
Dim loadClasses() As SampleClass
loadClasses = serializer2.Deserialize(fs2)
Dim loadClass As SampleClass
For Each loadClass In loadClasses
    Console.WriteLine("String:{0} Integer:{1}", _
        loadClass.Message, loadClass.Number)
Next
fs2.Close()
[C#]
////次のクラスが宣言されているものとする
//public class SampleClass
//{
//    public int Number;
//    public string Message;
//}

//保存するオブジェクトの配列を作成
SampleClass[] myClasses = new SampleClass[10];
for (int i = 0; i < 10; i++)
{
    myClasses[i] = new SampleClass();
    myClasses[i].Number = i;
    myClasses[i].Message = i.ToString() + "だよ。";
}

//XMLファイルに保存する
System.Xml.Serialization.XmlSerializer serializer1 =
    new System.Xml.Serialization.XmlSerializer(
        typeof(SampleClass[]));
System.IO.FileStream fs1 =
    new System.IO.FileStream(
        @"C:\test.xml", System.IO.FileMode.Create);
serializer1.Serialize(fs1, myClasses);
fs1.Close();

//保存した内容を復元する
System.Xml.Serialization.XmlSerializer serializer2 =
    new System.Xml.Serialization.XmlSerializer(
        typeof(SampleClass[]));
System.IO.FileStream fs2 =
    new System.IO.FileStream(
        @"C:\test.xml", System.IO.FileMode.Open);
SampleClass[] loadClasses;
loadClasses = (SampleClass[]) serializer2.Deserialize(fs2);

//復元した内容を表示する
foreach (SampleClass loadClass in loadClasses)
{
    Console.WriteLine("string:{0} int:{1}",
        loadClass.Message, loadClass.Number);
}
fs2.Close();

保存されたXMLファイルの内容は次のようになります。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。