Windows APIを使わずにiniファイルを読む方法

開発環境

  • C#
  • Visual Studio 2019

背景

  • C#でiniファイルを読むための一般的な方法は、おそらくWindows APIを使う方法。
    [DllImport("kernel32.dll")]で読み込むやつ。
    この方法については調べると沢山出てくるので割愛。(一部参考サイトで紹介)
  • 何かの事情でWindows APIを使えない時のために、iniファイルを読み込むコードを作りました。

iniファイルサンプル(setting.ini)

[AAA]
filename=aaa.txt
path=C:\Users\abc\Documents
[BBB]
filename=bbb.txt
path="C:\Users\abc\Documents"

サンプルコード

// iniファイルのパスを指定
string iniFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "setting.ini");

// 値読み込み
string filenameA = ReadIniValue("AAA", "filename", "", iniFilePath);
string pathA = ReadIniValue("AAA", "path", "", iniFilePath);
string filenameB = ReadIniValue("BBB", "filename", "bbb.txt", iniFilePath);
string pathB = ReadIniValue("BBB", "path", "C:\Users\abc\Documents", iniFilePath);

/// <summary>
/// iniファイルの値を読み込み
/// </summary>
private string ReadIniValue(string section, string key, string defaultValue, string filePath)
{
    try
    {
        // iniファイルをUTF-8で読み込む
        using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
        {
            string line;
            string currentSection = null;  // 現在処理中のセクション

            while ((line = reader.ReadLine()) != null)
            {
                // 各行を読み込み
                line = line.Trim();
                // セクションの始まりを検出
                if (line.StartsWith("[") && line.EndsWith("]"))
                {
                    currentSection = line.Substring(1, line.Length - 2).Trim();
                }
                else if (currentSection != null && currentSection.Equals(section, StringComparison.OrdinalIgnoreCase))
                {
                    // 現在処理中のセクションが指定されたセクションと一致する場合
                    if (line.StartsWith($"{key}=", StringComparison.OrdinalIgnoreCase))
                    {
                        // 該当のキーが見つかった場合、値を取得
                        string value = line.Substring(key.Length + 1).Trim();

                        // ダブルクオーテーションで囲まれている場合は取り除く
                        if (!string.IsNullOrEmpty(value) && value.StartsWith("\"") && value.EndsWith("\""))
                        {
                            value = value.Substring(1, value.Length - 2);
                        }
                        return value;
                    }
                }
            }
        }
        // 該当するキーが見つからなかった場合はデフォルト値を返す
        return defaultValue;
    }
    catch (Exception ex)
    {
        return defaultValue;
    }
}

サンプルコードの補足説明

  • iniファイルのパスはアプリケーションフォルダにしていますが、必要に応じて設定してください。
  • [BBB]セクションのpathのように、値がダブルクオーテーションで囲まれている場合にも対応しました。
  • 値が読み取れなかった場合のデフォルト値として、[AAA]セクションは空文字、[BBB]セクションはsetting.iniと同じ値を設定しています。ここは状況に応じてください。
  • iniFilePathReadIniValue()関数は、実際は別クラスで独立させたほうが使い勝手が良いです。
  • 読んだ値が文字化けする場合はStreamReaderの第二引数を適切に設定してください。(サンプルではUTF-8)
  • セクション文字列の検出には大文字小文字を区別していません。
    区別したい場合はStringComparison.OrdinalIgnoreCaseStringComparison.Ordinalにしてください。
  • catchの中は必要に応じて例外処理を行ってください。

参考サイト(Window APIを使う方法)