Tuesday, 1 July 2014

INI files are dead... Long live INI files!

There was a time when INI files ruled the world of configuration. Since then, we've been told on numerous occasions by many people that we should rather be using XML. Or a SQLite database. Or something else, perhaps.

Now, don't get me wrong -- SQLite has its merits and XML is great if you want to store hierarchical data or if you need to configure your .NET application (which happens to already speak the lingo). But the reality is that INI serves quite well for a number of uses -- indeed, it can also be used to store hierarchical data, as you'd see if you checked out the innards of a .reg file. In particular, INI files are dead-easy to parse, both by machine and man -- and the latter is an advantage if you have nothing to hide and no need for quick read/write (where you might, for example, use SQLite). It's also a simple file-store so platform and library requirements are minimal. It's probably the easiest way to store structured configuration data and I still use it for projects unless I absolutely have to use something else.

A relatively small, simple part of the PeanutButter suite is the INI reader/writer/storage class PeanutButter.INI.INIFile. Usage is quite simple:


var ini = new INIFile("C:\\path\\to\\your\\iniFile.ini");
var someConfiguredValue = ini["colors"]["FavouriteColor"];
ini["Geometry"]["Left"] = "123";
ini.Persist();

In thesnippet above, we instantiate an INIFile class with a path to a file to use as the default persistence store. This file doesn't have to exist right now (and if it doesn't, it will be created with the Persist() call).

INIFile presents the data present in the source as a Dictionary<string, Dictionary<string, string>>, with indexing on the INIFile instance itself, making the syntax quite easy to use. Sections are created as and when you need them. Section and key names (such as "Geometry" and "Left" above) are case-insensitive to make access easier (and more compliant with the behavior of the older win32 calls for INI handling).

The parser tolerates empty lines and comments as well as empty keys (which are returned as an empty string).

Of course, you don't have to have a backing store to start with (or at all), and you can always override the output path with a parameter to Persist(). In addition, you can re-use the same INIFile, loading in a file from another path with the Load() method or loading with a pure string with the Parse() method.

Once again, the class has been developed on an as-required basis. It does much of what I want it to do (though I'd like it to persist comments on re-writing; that may come later). I hope that it can be of use to someone else too. I've lost count of how many times I've implemented an INI reader/writer. Hopefully, this is one of the last...

Update: I can't seem to comment on this article, so if you want to find out more (eg how to use INIFile), please check out the tests at GitHub which should illustrate usage. If there's not enough info there to use INIFile, please open an issue at the PeanutButter issue tracker so the conversation can be tracked for anyone else looking to use INIFile.

Thanks for reading!

1 comment:

  1. I have been trying to get the C# Application Settings to work with external files and have failed. I have got it to work with the internal file with no issue but I really need to save multiple configuration files for my app.
    You code looks really interesting. I have loaded it into my project from NuGet but am now stuck. I have only been using c# for a few days so most of what you write goes over my head. Do you have any detailed instructions of how to set this up? What files do I create. Where do I save/place them? That sort of thing. Thanks.

    ReplyDelete

What's new in PeanutButter?

Retrieving the post... Please hold. If the post doesn't load properly, you can check it out here: https://github.com/fluffynuts/blog/...