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

自分で作成したクラスをファイルに保存する方法です。
DataContractSerializerを使用してXML形式で保存します。

DataContractSerializer は System.Runtime.Serialization を使います。
多分初期設定では参照設定がないので追加して下さいね。


早速ですが、読み書き用のクラスにまとめました。 ジェネリック仕様になります。

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
public class FileXML {
  /// <summary>
  /// XMLファイルに保存
  /// </summary>
  static public bool Save<T>( T obj, string FilePath ) {
    try {
      // XmlSerializerを使ってファイルに保存(T型オブジェクトの内容を書き込む)
      var serializer = new DataContractSerializer(typeof(T));

      using( var fs = new FileStream(FilePath, FileMode.Create) )
      using( var xw = XmlWriter.Create(fs, new XmlWriterSettings {
        Indent = true,
        IndentChars = "\t"
      }) ) {
        // オブジェクトをシリアル化してXMLファイルに書き込む
        serializer.WriteObject(xw, obj);
      }

    } catch( Exception ) {
      return false;
    }
    return true;
  }

  /// <summary>
  /// XMLファイルを読み込み
  /// </summary>
  static public T Load<T>( string FilePath ) where T: new() {
    try {
      using( var sr = new StreamReader(FilePath) )
      using( var xr = XmlReader.Create(sr, new XmlReaderSettings() )) {
        // XMLをオブジェクトに読み込む
        var serializer = new DataContractSerializer(typeof(T));

        // XMLファイルを読み込み、逆シリアル化(復元)する
        return (T)serializer.ReadObject(xr);
      }
    } catch( Exception ) {
      return default(T);
    }
  }
}


保存するオブジェクトのクラスを作成します。

public class 保存クラス {
	public int PublicNum1;

	private int PrivateNum2;
	public void SetNumber(int num) {
		this.PrivateNum2 = num;
	}

	public int PublicProperty3 { get; set; }

	private int PrivateProperty4 { get; set; }
	public void SetNumberProperty( int num ) {
		this.PrivateProperty4 = num;
	}
}

実際に使うとこんな感じ

// 保存
var Save = new 保存クラス();
  Save.PublicNum1 = 100;
  Save.SetNumber(200);
  Save.PublicProperty3 = 300;
  Save.SetNumberProperty(400);

FileXML.Save<保存クラス>(Save, "./保存.xml");


// 読込
var Load = FileXML.Load<保存クラス>("./保存.xml");
// Load
//   PublicNum1      100
//   PrivateNum2       0
//   PublicProperty3   300
//   PrivateProperty4    0

出力されるファイルの中身がこちら
読込したデータからわかるようにPublicのものが全て保存されます

<?xml version="1.0" encoding="utf-8"?>
<保存クラス xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB">
	<PublicNum1>100</PublicNum1>
	<PublicProperty3>300</PublicProperty3>
</保存クラス>

Privateや保存したいデータを指定する場合は[DataContract]属性をクラスにつけて、保存したいフィールドやプロパティに[DataMember]属性を付けます。

using System.Runtime.Serialization;

[DataContract]
public class 保存クラス {
	[DataMember]
	public int PublicNum1;

	[DataMember]
	private int PrivateNum2;
	public void SetNumber(int num) {
		this.PrivateNum2 = num;
	}

	//[DataMember] ← 付けないと保存されない
	public int PublicProperty3 { get; set; }

	[DataMember]
	private int PrivateProperty4 { get; set; }
	public void SetNumberProperty( int num ) {
		this.PrivateProperty4 = num;
	}
}

PublicProperty3 は Public ですが [DataMember]をつけていないので保存されません。

<?xml version="1.0" encoding="utf-8"?>
<保存クラス xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB">
	<PublicNum1>100</PublicNum1>
	<PrivateNum2>200</PrivateNum2>
	<PrivateProperty4>400</PrivateProperty4>
</保存クラス>


ちなみにオブジェクトなら何でも保存できるので、こんなのもできます

var tuple = Tuple.Create(10, 20, 30, "string");
FileXML.Save<Tuple<int,int,int,string>>(tuple, "./保存.xml");
<?xml version="1.0" encoding="utf-8"?>
<TupleOfintintintstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System">
	<m_Item1>10</m_Item1>
	<m_Item2>20</m_Item2>
	<m_Item3>30</m_Item3>
	<m_Item4>string</m_Item4>
</TupleOfintintintstring>


こんな感じで好き放題保存してやりましょう!


参考:
DataContractSerializerを使って、オブジェクトのXMLシリアル化、逆シリアル化を行う: .NET Tips: C#, VB.NET
neue cc - .NETの標準シリアライザ(XML/JSON)の使い分けまとめ