オブジェクトの値をXMLファイルに保存する、開く
ある程度複雑なアプリケーションの場合は EXE 単体で動作することはなく、EXE と共にパラメータファイルが必要になる場合が多いです。
2022年現在のトレンドとしては、そういったパラメータファイルには json 形式が用いられる場合が多いです。その次に XML 形式でしょうか。さすがに ini ファイル形式を新規案件で採用することは無さそうです。
ここでは、オブジェクトのフィールドの値を XML 形式で保存したり、開いたりするコードを示します。
まずこちらがクラスオブジェクトの定義です。
using System;
namespace aaa
{
public class TheParametersObject
{
public int ValueI;
public long ValueL;
public double ValueD;
public float ValueF;
public String ValueS;
public bool ValueB;
public TheParametersObject()
{
ValueI = 123;
ValueL = 456;
ValueD = 7.89;
ValueF = 12.34f;
ValueS = "hello";
ValueB = true;
}
public void Nop()
{
// NOP.
}
public bool ReturnTrue()
{
return true;
}
public bool ReturnFalse()
{
return false;
}
}
}
XMLファイルのパスは const String で決め打ちにしてあります。
c:/tmp/parameters.xml
です。
下記の名前空間の追加をお忘れなく。
using System.Xml.Serialization;
using System.IO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// この using 追加を忘れずに. Don't forget to add this sentence.
using System.Xml.Serialization;
using System.IO;
namespace aaa
{
public partial class Form1 : Form
{
// 拡張子は XML である必要はない.
// TXT のほうがテキストエディタでラクに開ける.
const String FILEPATH_PRM = "c:/tmp/parameters.xml";
// データをよみこむオブジェクト.
TheParametersObject MyObj = new TheParametersObject();
public Form1()
{
InitializeComponent();
}
// オブジェクトのフィールドの値をXMLファイル形式で保存する.
private void menuFileSave_Click( object sender, EventArgs e )
{
// インスタンスが生成されているかいちおうチェックする.
if ( MyObj == null )
{
MessageBox.Show( "MyObj is NULL." );
return;
}
// XML読み書きクラスを生成する.
XmlSerializer xmser = new XmlSerializer( typeof( TheParametersObject ) );
try
{
// BOM無しUTF8エンコーディング.
Encoding enc = new UTF8Encoding( false );
// ファイルに書き込む.
using ( StreamWriter sw = new StreamWriter( FILEPATH_PRM, false, enc ) )
{
xmser.Serialize( sw, MyObj );
sw.Close();
}
}
catch ( Exception excp )
{
MessageBox.Show( excp.Message );
return;
}
}
// XMLファイル形式で記述された値をオブジェクトのフィールドに読み込む.
private void menuFileOpen_Click( object sender, EventArgs e )
{
// ファイルがあるか調べる.
if ( File.Exists( FILEPATH_PRM ) == false )
{
String strerr = String.Format( "File.Exists( {0} ) is false.", FILEPATH_PRM );
MessageBox.Show( strerr );
return;
}
// インスタンスが生成されているかいちおうチェックする.
if ( MyObj == null )
{
MessageBox.Show( "MyObj is NULL." );
return;
}
// XML読み書きクラスを生成する.
XmlSerializer xmser = new XmlSerializer( typeof( TheParametersObject ) );
try
{
// BOM無しUTF8エンコーディング.
Encoding enc = new UTF8Encoding( false );
// ファイルから読み出す.
using ( StreamReader sr = new StreamReader( FILEPATH_PRM, enc ) )
{
MyObj = ( TheParametersObject )( xmser.Deserialize( sr ) );
sr.Close();
}
}
catch ( Exception excp )
{
MessageBox.Show( excp.Message );
return;
}
// 内容表示用のストリングビルダ.
StringBuilder sb = new StringBuilder();
sb.AppendLine( MyObj.ValueI.ToString() );
sb.AppendLine( MyObj.ValueL.ToString() );
sb.AppendLine( MyObj.ValueD.ToString() );
sb.AppendLine( MyObj.ValueF.ToString() );
sb.AppendLine( MyObj.ValueS.ToString() );
sb.AppendLine( MyObj.ValueB.ToString() );
// メッセージボックスに表示する.
String strmsg = sb.ToString().Trim();
String cap = "実行結果";
MessageBox.Show( strmsg, cap );
}
}
}
50行目 と 93行目は、特に注意を払わなければならないところです。ここはテキストファイルの保存形式を決めるところです。UTF-8だとか、UTF-16だとか、BOMなしだとか、BOMありだとか、Shift-JISだとか、unicode だとか、ここは非常に重要なところです。
特に String 型のフィールドに日本語が格納されている場合に、ここの認識がおろそかだとドハマリします。2022年現在では、UTF-8 のBOMなしにしておけば問題ないでしょう。BOMありにしたかったら enc = new UTF8Encoding( true ); と引数に true を入れてください。
といってもこういうのはトレンドがどんどん変化していくので、プログラマ生活を続けているうちは流行に敏感でいてください。
最後にまったくの余談ですが、ini ファイルは本当に新規案件での採用はないのでしょうかね...
自分の周りではそういう事例がないだけで、実は現役だったりしたらどうしよう...