# Snippet C#: INI Files



## FordGT90Concept (Oct 26, 2008)

It's a shame that Microsoft has no native support for INI files in .NET so, we are forced to author our own.  This is my spin on an old flavor...

The problem I noticed with other INI readers is that use a LOT of methods for adding, removing, altering, and retreiving data.  A Dictionary<> can do that just as well if not better.  What I wanted to do is make everything accessible in this format:

```
value = IniInstance["section"]["key"];
```

It only makes sense, does it not?  I attached the relevant source.

To use these classes, first add them to your project and, if you want, change the namespace on both of them (make sure the namespace is same for both).

This is a snippet for how to create an instance of an IniFile:

```
IniFile ini = new IniFile("PathToFile.ini");
```

Now we'll want to see if this file already exists and if it does, load it; if not, create it and all necessary fields:

```
IniFile ini = new IniFile("PathToFile.ini");
if (ini.Exists())
  ini.Load();
else
{
  IniSection section = new IniSection();
  section.Add("key1", "value1");
  section.Add("key2", "value2");
  section.Add("key3", "value3");
  ini.Add("mySection1", section);

  section = new IniSection();
  section.Add("key1", "value1");
  section.Add("key2", "value2");
  section.Add("key3", "value3");
  ini.Add("mySection2", section);

  ini.Save();
}
```

The statements after the else are creating sections and then adding values to them.  At this point, you have data in the memory which you can now reference.  If you want to get a value from say "mySection2", "value3," do the following:

```
string value = ini["mysection2"]["value3"];
```

Note: all values in the ini are stored as strings so you may have to convert some values back to integer like this:

```
int value = Convert.ToInt32(ini["mysection2"]["value3"]);
```

If you want to modify an existing value, do the following:

```
ini["mysection2"]["value3"] = value;
```

And finally, when you're all done and getting ready to close the application, call the Save() method:

```
ini.Save()
```

Save writes everything in the memory to the hard drive which can be loaded up again via Load().


----------



## dstruktiv (Feb 21, 2010)

Hey mate thanks a lot for this! I wonder if you still use these forums... It's been well over a year since you posted this but I just found it very useful today. Only needed to edit one key in an ini file so didn't want something bloated or complicated. Thanks again!


----------



## FordGT90Concept (Feb 22, 2010)

I still use very similar code today. XD


----------



## nuva (Feb 28, 2010)

This code is great, i'm going to use this in one of my programmes 

is it possible to make a list of all sections in the ini files?


----------



## FordGT90Concept (Feb 28, 2010)

nuva said:


> is it possible to make a list of all sections in the ini files?


GetSections() will return a string[] of section names.  If you want the values too, just do a for or for loop to enumerate them.  For example:


```
foreach (string section in ini.GetSections())
{
  Console.WriteLine("[" + section + "]");
  foreach (string key in ini[section].GetKeys())
    Console.WriteLine(key + "=" + ini[section][key]);
  Console.WriteLine();
}
```


----------



## Deleted member 3 (Feb 28, 2010)

I always use streamreader and read each line. Add "bla=" for the value of bla on a line, if the line contains bla= I take the line and remove bla= which leaves me with the value. It works fine so I never gave it any more thought


----------



## FordGT90Concept (Feb 28, 2010)

The code loads the whole file (less comments) into the memory via strongly typed dictionaries.  It is much faster in execution and in usage than handling it as a file every time.


----------



## Deleted member 3 (Feb 28, 2010)

FordGT90Concept said:


> The code loads the whole file (less comments) into the memory via strongly typed dictionaries.  It is much faster in execution and in usage than handling it as a file every time.



I save relevant settings in memory, SQL connection strings and the likes. Reading it from file every time is indeed silly.


----------



## Kreij (Feb 28, 2010)

.Net now has outstanding support for XML files. I use that if I have to persist something.
But hey, whatever works.


----------



## FordGT90Concept (Feb 28, 2010)

XML files have too much dead space.  INI has only 4 bytes ([ ] \r \n) per section and 3 bytes (= \r \n) per data point.  XML has at 3 bytes (< / >) per tag and 5 if it has a closing tag (< > < / >).  Add in quotes (= " "), line breaks (\r \n), and tabs (\t)...it adds up fast.  9/10 times, INI is best.  There's only been 2-3 times where XML was better suited for the job (involved heavy nesting/properties per object and easily user editable).

They shouldn't have gotten rid of INI support.  It is still very useful.


----------



## MadTogger (May 9, 2010)

Hi FordGT90Concept,

your snippet is exactly what I was looking for for my project.

I have added the two classes and placed:-


```
using Ini;
```

at the top of my projects form code, placed:-


```
IniFile ini = new IniFile("PathToFile.ini");
			
			if (ini.Exists())
  ini.Load();
else
{
  ini.Add("mySection1");
  ini["mySection1"].Add("value1");
  ini["mySection1"].Add("value2");
  ini["mySection1"].Add("value3");
  ini.Add("mySection2");
  ini["mySection2"].Add("value1");
  ini["mySection2"].Add("value2");
  ini["mySection2"].Add("value3");
}
```

directly after:-


```
InitializeComponent();
```

I guess I am missing something because when running the project it throws up an Exception:-

*Keys must have an equal sign.*

which is in the *IniSection.cs*

Please could you advise me what I am doing wrong.

Also, I am guessing that the line:-


```
IniFile ini = new IniFile("PathToFile.ini");
```

I have to actually change *PathToFile* to a path where I want my *ini* to reside?

Sorry if this all seems pretty basic stuff but I am fairly new to c#.

Kind regards..,

MT


----------



## FordGT90Concept (May 11, 2010)

Sorry for not responding sooner.

The "Keys must have an equal sign." exception occurs when using IniSection.Add(line).  Line must contain an equal sign.  For example, "key=value" would work but "value" will not.  I always use IniSection.Add(key, defaultvalue).  For example, IniSection.Add("key", "value").  Because most don't have a defaultvalue, it is usually IniSection.Add("key", "").

The same applies for IniFile.Add(line) except that it expects [] rather than an equal sign.  The proper way to call it is IniFile.Add(sectionname, section).  For example:  IniFile.Add("mysection", New IniSection()).


I'll fix the section of code you posted:

```
IniFile ini = new IniFile("PathToFile.ini");
if (ini.Exists())
  ini.Load();
else
{
  IniSection section = new IniSection();
  section.Add("key1", "value1");
  section.Add("key2", "value2");
  section.Add("key3", "value3");
  ini.Add("mySection1", section);

  section = new IniSection();
  section.Add("key1", "value1");
  section.Add("key2", "value2");
  section.Add("key3", "value3");
  ini.Add("mySection2", section);

  ini.Save();
}
```
That should theoretically work.





MadTogger said:


> I have to actually change *PathToFile* to a path where I want my *ini* to reside?


Correct.  When you call Load or Save, that's where it is going to perform that operation.  Load reads the file there and Save writes the file there.  Load will error if the file doesn't exist.


Edit: I see my example was wrong on the original post, I'll update it.


----------



## MadTogger (May 11, 2010)

FordGT90Concept said:


> Sorry for not responding sooner.



Thanks, much appreciated.

Regards..,

MT


----------

