tags:

views:

196

answers:

5

I am trying to read an ini file that has the following format:

SETTING=VALUE 
SETTING2=VALUE2

I currently have the following code:

string cache = sr.ReadToEnd();                    
string[] splitCache = cache.Split(new string[] {"\n", "\r\n"}, StringSplitOptions.RemoveEmptyEntries);

Which gives me a list of settings, however, what I would like to do is read this into a dictionary. My question is, is there a way to do this without iterating through the entire array and manually populating the dictionary?

+4  A: 

Well, you could use LINQ and do

Dictionary<string, string> ini = (from entry in splitCache
                                  let key = entry.Substring(0, entry.FirstIndexOf("="))
                                  let value = entry.Substring(entry.FirstIndexOf("="))
                                  select new { key, value }).ToDictionary(e => e.key, e => e.value);

As Binary Worrier points out in the comments, this way of doing this has no advantages over the simple loop suggested by the other answers.

Edit: A shorter version of the block above would be

Dictionary<string, string> ini = splitCache.ToDictionary(
                                   entry => entry.Substring(0, entry.FirstIndexOf("="),
                                   entry => entry.Substring(entry.FirstIndexOf("="));
Jens
@pm_2. be aware that this simply hiding a very simple loop under some fairly ugly linq. +1 for answering the question as asked, however I'd rather the loop.
Binary Worrier
Other than the obvious readability issue, are there any other down-sides to using this method?
pm_2
@pm_2: You cannot step through LINQ expressions using the debugger. Other than that, I don't know any.
Jens
There's an upside. The compiler/runtime is more likely to be able to automatically parellize LINQ written code so that it can be ran on multiple CPUs than it can a loop.
Scott Langham
A: 

Why not read the file as separate lines, then loop over them splitting on the first =?

var dict = new Dictionary<string,string>();
foreach (var line in File.ReadAllLines(filename)) {
  var parts = line.Split('=', 2); // Maximum of 2 parts, so '=' in value ignored.
  dict.Add(parts[0], parts[1]);
}

(In .NET 4 replace ReadAllLines with ReadLines, to avoid creating the array, ReadLines returns IEnumerable<String> and reads the file lazily.)

Richard
should be `dict.Add(parts[0], parts[1]);`, shouldn't it?
ZombieSheep
@ZombieSheep: Of course it should :-) Corrected.
Richard
+3  A: 

What is wrong with iterating?

var lines = File.ReadAllLines("pathtoyourfile.ini");
var dict = new Dictionary<string, string>();

foreach(var s in lines)
{
     var split = s.Split("=");
     dict.Add(split[0], split[1]);
}
klausbyskov
+2  A: 

There's actually a Windows API for reading/writing INI files in kernel32.dll; see this CodeProject article for an example.

Will Vousden
+1  A: 

Try like this

 [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString")]

 public static extern int GetPrivateProfileString(string SectionName, string KeyName, string Default, StringBuilder Return_StringBuilder_Name, int Size, string FileName);

and call the function like this

 GetPrivateProfileString(Section_Name, "SETTING", "0", StringBuilder_Name, 10, "filename.ini");

The value can be accessed from StringBuilder_Name

Pramodh