Skip to content

Instantly share code, notes, and snippets.

@DamianSuess
Last active August 19, 2025 18:34
Show Gist options
  • Select an option

  • Save DamianSuess/4fc4480d440c0d457f1c7a25115287ac to your computer and use it in GitHub Desktop.

Select an option

Save DamianSuess/4fc4480d440c0d457f1c7a25115287ac to your computer and use it in GitHub Desktop.
Custom INI File Class - light-weight and simple
// The following was tested using RolsynPad 20.0
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
// Example usage
var ini = new IniFile();
ini.Load("config.ini");
ini.SetValue("MySection", "MyKey", "Somevalue12345");
var data1 = ini.GetValue("MySection", "MyKey");
Console.WriteLine("Data-1.1: " + data1);
ini.SetValue("MySection", "MyKey", "Data with spaces");
data1 = ini.GetValue("MySection", "MyKey");
Console.WriteLine("Data-1.2: " + data1);
var data2 = ini.GetValue("MySection", "MISSING_KEY");
Console.WriteLine("Invalid-Key: " + data2);
var data3 = ini.GetValue("NO_SECTION", "MISSING_KEY");
Console.WriteLine("Invalid-Section: " + data3);
// ----------
public class IniFile
{
public const char Semi = ';';
public const char Hash = '#';
public const char BracketOpen = '[';
public const char BracketClose = ']';
public const char Equals = '=';
private readonly Dictionary<string, Dictionary<string, string>> _iniData =
new(StringComparer.OrdinalIgnoreCase);
public PreferenceService()
{
}
public string? GetValue(string section, string key, string? defaultValue = null)
{
if (_iniData.ContainsKey(section) && _iniData[section].ContainsKey(key))
return _iniData[section][key];
return defaultValue;
}
public void Load(string filePath)
{
_iniData.Clear();
if (!File.Exists(filePath))
return;
string currentSection = string.Empty;
foreach (string line in File.ReadAllLines(filePath))
{
string trimmedLine = line.Trim();
// Skip empty lines and comments
if (string.IsNullOrWhiteSpace(trimmedLine) || trimmedLine.StartsWith(Semi) || trimmedLine.StartsWith(Hash))
continue;
if (trimmedLine.StartsWith(BracketOpen) && trimmedLine.EndsWith(BracketClose))
{
////currentSection = trimmedLine.Substring(1, trimmedLine.Length - 2);
currentSection = trimmedLine[1..^1];
if (!_iniData.ContainsKey(currentSection))
_iniData[currentSection] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
else if (trimmedLine.Contains(Equals))
{
int equalsIndex = trimmedLine.IndexOf(Equals);
////string key = trimmedLine.Substring(0, equalsIndex).Trim();
////string value = trimmedLine.Substring(equalsIndex + 1).Trim();
string key = trimmedLine[..equalsIndex].Trim();
string value = trimmedLine[(equalsIndex + 1)..].Trim();
if (!string.IsNullOrEmpty(currentSection) && _iniData.ContainsKey(currentSection))
_iniData[currentSection][key] = value;
}
}
}
public void Save(string filePath)
{
using StreamWriter writer = new(filePath);
foreach (var sectionEntry in _iniData)
{
writer.WriteLine($"{BracketOpen}{sectionEntry.Key}{BracketClose}");
foreach (var keyValuePair in sectionEntry.Value)
writer.WriteLine($"{keyValuePair.Key}{Equals}{keyValuePair.Value}");
// Add a blank line between sections for readability
writer.WriteLine();
}
}
public void SetValue(string section, string key, string value)
{
if (!_iniData.ContainsKey(section))
_iniData[section] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
_iniData[section][key] = value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment