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と同じ値を設定しています。ここは状況に応じてください。
iniFilePath
やReadIniValue()
関数は、実際は別クラスで独立させたほうが使い勝手が良いです。- 読んだ値が文字化けする場合は
StreamReader
の第二引数を適切に設定してください。(サンプルではUTF-8) - セクション文字列の検出には大文字小文字を区別していません。
区別したい場合はStringComparison.OrdinalIgnoreCase
をStringComparison.Ordinal
にしてください。 catch
の中は必要に応じて例外処理を行ってください。