I am trying to parse an ini file and grab specific key-value pairs,given a section name and key name. I use the following code, using Linq, and it works if I don't include the key name in its search but returns empty list if I do.
Sample ini section:
[INSTANCES]
NUMVTC=3
VTC=0,3330,ABCD,DESCR0
VTC=1,3331,EFGH,DESCR1
VTC=2,3332,IJKL,DESCR2
partial code to parse the file
List<IniEntry> vals = File.ReadLines(sMappingFilePath)
.SkipWhile(line => !line.StartsWith("[instances]",
StringComparison.CurrentCultureIgnoreCase))
.Skip(1)
.TakeWhile(line => !string.IsNullOrEmpty(line) && line.StartsWith("vtc", StringComparison.CurrentCultureIgnoreCase)) // The "vtc" portion breaks it
.Select(line => new IniEntry(line.Split('=')[0], line.Split('=')[1])).ToList();
public class IniEntry
{
public string Key { get; set; }
public string Value { get; set; }
public IniEntry(string key, string val) {
Key = key;
Value = val;
}
}
If I remove the part that says "line.StartsWith("vtc"...", it works and returns all key-value pairs under INSTANCES, including NUMVTC=3, which I want to skip.
I want to make this into a generic function that would return key-value pairs given a section name and key name.
Update
I modified the code, based on suggestions and comments, and made it to a generic function that takes .ini file path, section name and key name and return list on IniEntry objects.
public static List<IniEntry> GetIniSectionDataList(string sIniFilePath, string sSection, string sKey)
{
List<IniEntry> ls = new List<IniEntry>();
if (string.IsNullOrEmpty(sIniFilePath))
{
return ls;
}
// In case user enters **[blah** , or **blah]**
sSection = sSection.Replace("[", string.Empty).Replace("]", string.Empty);
sSection = "[" + sSection + "]";
ls = File.ReadLines(sIniFilePath)
.SkipWhile(line => !line.StartsWith(sSection, StringComparison.CurrentCultureIgnoreCase))
.Where(line => line.StartsWith(sKey, StringComparison.CurrentCultureIgnoreCase))
//.Skip(1)
.TakeWhile(line => !string.IsNullOrEmpty(line))
.Select(line => new IniEntry(line.Split('=')[0], line.Split('=')[1]))ToList();
return ls;
}
I call it using:
List<IniEntry> vals = TCLogFile.GetIniSectionDataList(sMappingFilePath, "instances", "vtc");
Where, here is a quick mockup.NUMVTCif you want to make this "generic"? Just let it cook, then use GroupBy ?