【C#】自作のクラスでiniファイルを読み書きする|サンプルコード付き完全ガイド

この記事では、C#で自作のクラスを用いてiniファイルを読み書きする方法を解説します。iniファイルは設定情報を保存する際に便利な形式です。この記事では、以下の流れで進めます。

iniファイルとは何か

NIファイルは、設定情報を保存するためのシンプルなテキストファイル形式です。各設定はセクション([セクション名])ごとにグループ化され、キーと値のペアとして記述されます。 例えば、以下のような形式です:

[General]
Key1=Value1
Key2=Value2

[Settings]
Option1=True
Option2=123

基本的なiniファイルの構造

NIファイルには以下の特徴があります:

  • セクション: [セクション名] で定義されます。
  • キーと値:○=●の○がキー、●が値を表す。
  • コメント: ; または # で始まる行はコメントとして扱われます。

iniファイルを読み書きするコード

以下は、iniファイルを操作するためのC#コードです。 このクラスは以下の機能を持ちます:

  • iniファイルの読み込み
  • セクションとキーを指定して値を取得
  • 新しい値を設定 – ファイルに保存
public class IniFile
{
    private readonly Dictionary<string, Dictionary<string, string>> _data = new Dictionary<string, Dictionary<string, string>>();

    // コンストラクタでファイルを読み込み、解析
    public IniFile(string filePath)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("指定されたファイルが見つかりません。", filePath);

        ParseIniFile(filePath);
    }

    // 指定したセクションとキーから値を取得
    public string GetValue(string section, string key, string defaultValue = "")
    {
        if (_data.ContainsKey(section) && _data[section].ContainsKey(key))
            return _data[section][key];

        return defaultValue;
    }

    // セクションの追加や変更
    public void SetValue(string section, string key, string value)
    {
        if (!_data.ContainsKey(section))
            _data[section] = new Dictionary<string, string>();

        _data[section][key] = value;
    }

    // 解析処理
    private void ParseIniFile(string filePath)
    {
        string currentSection = "";

        foreach (var line in File.ReadLines(filePath))
        {
            string trimmedLine = line.Trim();

            // コメントや空行をスキップ
            if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith(";") || trimmedLine.StartsWith("#"))
                continue;

            // セクションヘッダの処理
            if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]"))
            {
                currentSection = trimmedLine.Substring(1, trimmedLine.Length - 2).Trim();
                if (!_data.ContainsKey(currentSection))
                    _data[currentSection] = new Dictionary<string, string>();
            }
            else
            {
                // キーと値のペアを解析
                var keyValue = trimmedLine.Split(new[] { '=' }, 2);
                if (keyValue.Length == 2)
                {
                    string key = keyValue[0].Trim();
                    string value = keyValue[1].Trim();

                    if (!_data.ContainsKey(currentSection))
                        _data[currentSection] = new Dictionary<string, string>();

                    _data[currentSection][key] = value;
                }
            }
        }
    }

    // iniファイルへの保存
    public void Save(string filePath)
    {
        using (StreamWriter writer = new StreamWriter(filePath))
        {
            foreach (var section in _data)
            {
                writer.WriteLine($"[{section.Key}]");
                foreach (var kvp in section.Value)
                {
                    writer.WriteLine($"{kvp.Key}={kvp.Value}");
                }
                writer.WriteLine();
            }
        }
    }
}

実際の使用例

以下の例は、上記のクラスを使った実際の使用方法を示しています。

iniファイルの読み出し:

// ini ファイルの解析・読み込み
IniFile ini = new IniFile("config.ini");
string value = ini.GetValue("General", "Key1", "DefaultValue");

これでconfig.iniファイルにある[General]セクションにあるKey1キーの値を取得することができます。

ini ファイルのキーの編集・ファイル保存

// ini ファイルのキーの編集
ini.SetValue("General", "Key1", "NewValue1");

// INI ファイルの保存
ini.Save("config.ini");

これで、[General]セクションにあるKey1キーの値を”NewValue1″に変更、そしてその変更後の値でiniファイルを保存することができます。

変更後のiniファイル:

[General]
Key1=NewValue1
Key2=Value2

[Settings]
Option1=True
Option2=123

注意点とベストプラクティス

  • ファイルパスの検証: ファイルが存在しない場合のエラーハンドリングを適切に行う。
  • 競合の回避: 複数のプロセスで同じiniファイルを操作する場合は注意が必要です。
  • コメントの保持: このクラスではコメント行は保持されません。必要に応じて拡張可能です。
  • GetValueで指定したキーが存在しない場合、第3引数のデフォルト値を返しています。必要に応じて自身でカスタマイズしてみるといいかと思います。