A simple .ini File parser for C#
Okay, so back in the old days, we had INI Files to store settings in. Those files are very simple:
[Section]
Key=Value
SomeOtherKey=SomeOtherValue[AnotherSection]
Hello=World
Hardly exciting, but it gets the job done very well. Today I wanted to work with INI Files in my C# Application, both for reading and writing. But as I just found out, .net does not have built in functions for working with .ini files. It looks like they want everyone to work with XML Files now. Well, apart from the fact that XML looks like my keyboard puked on my hard drive and that the format is unneccesarily complicated for this purpose, I also found that reading and writing them is rather complicated, especially since the XmlSerializer has some stupid restrictions (one being that the class needs to be public - have they never heard of reflection?).
It's great that the .net Framework is so powerful - I believe I can write a function that downloads an MP3 off the internet and uses it to generate a gradient in an image which then gets encrypted and sent per e-Mail in maybe 5 lines or so, but when it comes to something simple as saving some Key/Value Pairs, I still need a crapton of code. So I binged the internets a bit and found some code that uses P/Invoke to call Kernel functions to handle ini files, but I want to avoid P/Invoke at all costs. So in the end I simply wrote a class to Load/Save Ini Files.
It's a simple class to interact with a simple file format that was created to store Key/Value pairs and that just works. Seriously, don't change what isn't broken. The class is licensed under WTFPL and can be downloaded here.
Thanks! This saves me a bit of time.
I share your exact sentiments. I was in mid-grumble and was about to write something like this in frustration, then stumbled here.
Long live simplicity and single file functionality. XML is fugly and people should be strung up for having simple utilities be a "crapton" of code. Ever had a peep at the directory entrails of java (and other) libraries? Ugh.
You would love python.
First encounter with WTFPL... love it.
Perhaps the best reason to roll your own P/Invoke-free .ini code is that the P/Invoked native functions DO NOT WORK for perfectly valid .ini files, particularly for the first section in the file.
My memory may be failing, but I seem to recall these problems using the P/Invoked functions:
* You cannot retrieve a list of sections
* Starting the first section on the first line renders the section inaccessible
Hi, thanks for the class.
I modified the pattern to include trimming of whitespace between key, equals sign and value, trimming of whitespace after a value, and added an ignore rule for lines that start with ; or # char. A key still needs to be a non-whitespace containing word though.
private readonly Regex _keyValueRegex = new Regex(@"\s*(?[^=;#\s]+)\s*=\s*(?.+?)(?=\s*$)");
You can try it out on this text (I hope your blog doesn't change any characters)
; last modified 6 June 2012 by John Doe
[owner]
name=John Doe
organization = Acme Widgets Inc.
[database]
; use IP address in case network name resolution is not working
server=192.0.2.62
port=143
file = "payroll.dat"
Thanks a lot! I'll update the code and add an attribution line 🙂
Actually that regex isn't _quite_ right. Technically, it's valid for a key to contain ; # or a space, according to most parsers. It's only if the line (ignoring spaces) contains a ; or # that it's considered a comment.
Here's my version with the changes (I started from the original):
private readonly Regex _keyValueRegex = new Regex(@"^\s*(?[^;#=\s][^=]+?)\s*=\s*(?.+)");
(In case wordpress messes up that line: http://paste.ubuntu.com/1098831/)
Yeah, wordpress is removing the Key and Value names from the regex. Look at the pastebin for the actual code.