By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,984 Members | 1,011 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Reading and parsing an INI file in C#

100+
P: 115
This class makes use of System.Collections.Hashtable to enumerate all the settings in an INI file for easy access. Its very simplistic, and completely re-useable. Solid addition for any app that requires a settings file.

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4.  
  5. public class IniParser
  6. {
  7.     private Hashtable keyPairs = new Hashtable();
  8.     private String iniFilePath;
  9.  
  10.     private struct SectionPair
  11.     {
  12.         public String Section;
  13.         public String Key;
  14.     }
  15.  
  16.     /// <summary>
  17.     /// Opens the INI file at the given path and enumerates the values in the IniParser.
  18.     /// </summary>
  19.     /// <param name="iniPath">Full path to INI file.</param>
  20.     public IniParser(String iniPath)
  21.     {
  22.         TextReader iniFile = null;
  23.         String strLine = null;
  24.         String currentRoot = null;
  25.         String[] keyPair = null;
  26.  
  27.         iniFilePath = iniPath;
  28.  
  29.         if (File.Exists(iniPath))
  30.         {
  31.             try
  32.             {
  33.                 iniFile = new StreamReader(iniPath);
  34.  
  35.                 strLine = iniFile.ReadLine();
  36.  
  37.                 while (strLine != null)
  38.                 {
  39.                     strLine = strLine.Trim().ToUpper();
  40.  
  41.                     if (strLine != "")
  42.                     {
  43.                         if (strLine.StartsWith("[") && strLine.EndsWith("]"))
  44.                         {
  45.                             currentRoot = strLine.Substring(1, strLine.Length - 2);
  46.                         }
  47.                         else
  48.                         {
  49.                             keyPair = strLine.Split(new char[] { '=' }, 2);
  50.  
  51.                             SectionPair sectionPair;
  52.                             String value = null;
  53.  
  54.                             if (currentRoot == null)
  55.                                 currentRoot = "ROOT";
  56.  
  57.                             sectionPair.Section = currentRoot;
  58.                             sectionPair.Key = keyPair[0];
  59.  
  60.                             if (keyPair.Length > 1)
  61.                                 value = keyPair[1];
  62.  
  63.                             keyPairs.Add(sectionPair, value);
  64.                         }
  65.                     }
  66.  
  67.                     strLine = iniFile.ReadLine();
  68.                 }
  69.  
  70.             }
  71.             catch (Exception ex)
  72.             {
  73.                 throw ex;
  74.             }
  75.             finally
  76.             {
  77.                 if (iniFile != null)
  78.                     iniFile.Close();
  79.             }
  80.         }
  81.         else
  82.             throw new FileNotFoundException("Unable to locate " + iniPath);
  83.  
  84.     }
  85.  
  86.     /// <summary>
  87.     /// Returns the value for the given section, key pair.
  88.     /// </summary>
  89.     /// <param name="sectionName">Section name.</param>
  90.     /// <param name="settingName">Key name.</param>
  91.     public String GetSetting(String sectionName, String settingName)
  92.     {
  93.         SectionPair sectionPair;
  94.         sectionPair.Section = sectionName.ToUpper();
  95.         sectionPair.Key = settingName.ToUpper();
  96.  
  97.         return (String)keyPairs[sectionPair];
  98.     }
  99.  
  100.     /// <summary>
  101.     /// Enumerates all lines for given section.
  102.     /// </summary>
  103.     /// <param name="sectionName">Section to enum.</param>
  104.     public String[] EnumSection(String sectionName)
  105.     {
  106.         ArrayList tmpArray = new ArrayList();
  107.  
  108.         foreach (SectionPair pair in keyPairs.Keys)
  109.         {
  110.             if (pair.Section == sectionName.ToUpper())
  111.                 tmpArray.Add(pair.Key);
  112.         }
  113.  
  114.         return (String[])tmpArray.ToArray(typeof(String));
  115.     }
  116.  
  117.     /// <summary>
  118.     /// Adds or replaces a setting to the table to be saved.
  119.     /// </summary>
  120.     /// <param name="sectionName">Section to add under.</param>
  121.     /// <param name="settingName">Key name to add.</param>
  122.     /// <param name="settingValue">Value of key.</param>
  123.     public void AddSetting(String sectionName, String settingName, String settingValue)
  124.     {
  125.         SectionPair sectionPair;
  126.         sectionPair.Section = sectionName.ToUpper();
  127.         sectionPair.Key = settingName.ToUpper();
  128.  
  129.         if (keyPairs.ContainsKey(sectionPair))
  130.             keyPairs.Remove(sectionPair);
  131.  
  132.         keyPairs.Add(sectionPair, settingValue);
  133.     }
  134.  
  135.     /// <summary>
  136.     /// Adds or replaces a setting to the table to be saved with a null value.
  137.     /// </summary>
  138.     /// <param name="sectionName">Section to add under.</param>
  139.     /// <param name="settingName">Key name to add.</param>
  140.     public void AddSetting(String sectionName, String settingName)
  141.     {
  142.         AddSetting(sectionName, settingName, null);
  143.     }
  144.  
  145.     /// <summary>
  146.     /// Remove a setting.
  147.     /// </summary>
  148.     /// <param name="sectionName">Section to add under.</param>
  149.     /// <param name="settingName">Key name to add.</param>
  150.     public void DeleteSetting(String sectionName, String settingName)
  151.     {
  152.         SectionPair sectionPair;
  153.         sectionPair.Section = sectionName.ToUpper();
  154.         sectionPair.Key = settingName.ToUpper();
  155.  
  156.         if (keyPairs.ContainsKey(sectionPair))
  157.             keyPairs.Remove(sectionPair);
  158.     }
  159.  
  160.     /// <summary>
  161.     /// Save settings to new file.
  162.     /// </summary>
  163.     /// <param name="newFilePath">New file path.</param>
  164.     public void SaveSettings(String newFilePath)
  165.     {
  166.         ArrayList sections = new ArrayList();
  167.         String tmpValue = "";
  168.         String strToSave = "";
  169.  
  170.         foreach (SectionPair sectionPair in keyPairs.Keys)
  171.         {
  172.             if (!sections.Contains(sectionPair.Section))
  173.                 sections.Add(sectionPair.Section);
  174.         }
  175.  
  176.         foreach (String section in sections)
  177.         {
  178.             strToSave += ("[" + section + "]\r\n");
  179.  
  180.             foreach (SectionPair sectionPair in keyPairs.Keys)
  181.             {
  182.                 if (sectionPair.Section == section)
  183.                 {
  184.                     tmpValue = (String)keyPairs[sectionPair];
  185.  
  186.                     if (tmpValue != null)
  187.                         tmpValue = "=" + tmpValue;
  188.  
  189.                     strToSave += (sectionPair.Key + tmpValue + "\r\n");
  190.                 }
  191.             }
  192.  
  193.             strToSave += "\r\n";
  194.         }
  195.  
  196.         try
  197.         {
  198.             TextWriter tw = new StreamWriter(newFilePath);
  199.             tw.Write(strToSave);
  200.             tw.Close();
  201.         }
  202.         catch (Exception ex)
  203.         {
  204.             throw ex;
  205.         }
  206.     }
  207.  
  208.     /// <summary>
  209.     /// Save settings back to ini file.
  210.     /// </summary>
  211.     public void SaveSettings()
  212.     {
  213.         SaveSettings(iniFilePath);
  214.     }
  215. }
Example of usage:

INI File (C:\test.ini):

Expand|Select|Wrap|Line Numbers
  1. [AppSettings]
  2. msgPart1=Hello
  3. msgPart2= World
  4.  
  5. [Punctuation]
  6. ex=!
TestApp:

Expand|Select|Wrap|Line Numbers
  1. public class TestParser
  2. {
  3.     public static void Main()
  4.     {
  5.         IniParser parser = new IniParser(@"C:\test.ini");
  6.  
  7.         String newMessage;
  8.  
  9.         newMessage = parser.GetSetting("appsettings", "msgpart1");
  10.         newMessage += parser.GetSetting("appsettings", "msgpart2");
  11.         newMessage += parser.GetSetting("punctuation", "ex");
  12.  
  13.         //Returns "Hello World!"
  14.         Console.WriteLine(newMessage);
  15.         Console.ReadLine();
  16.     }
  17. }
May 28 '08 #1
Share this Article
Share on Google+
5 Comments


10K+
P: 13,264
What about comments in the ini file?
Jun 10 '08 #2

P: 1
If you look through the code - all you have to do is to add another conditional statement as shown here (modified sections in bold):
Expand|Select|Wrap|Line Numbers
  1. if (strLine.StartsWith("[") && strLine.EndsWith("]"))
  2. {
  3.   currentRoot = strLine.Substring(1, strLine.Length - 2);
  4. }
  5. else
  6. {
  7.   if (strLine.StartsWith("'")) {
  8.     // assuming comments start with the apostrophe
  9.     // do nothing
  10.   } else 
  11.   {
  12.     keyPair = strLine.Split(new char[] { '=' }, 2);
  13.     SectionPair sectionPair;
  14.     String value = null;
  15.  
  16.     if (currentRoot == null)
  17.       currentRoot = "ROOT";
  18.  
  19.     sectionPair.Section = currentRoot;
  20.     sectionPair.Key = keyPair[0];
  21.  
  22.     if (keyPair.Length > 1)
  23.       value = keyPair[1];
  24.  
  25.     keyPairs.Add(sectionPair, value);
  26.   }
  27. }
Jul 27 '09 #3

P: 1
My kingdom for this parser in a class.cs file...

I'm trying to get this wedged into a class file so I can use it in a few places, since I really do like the layout of it, but when I move it and put it into a namespace it just acts all wonky on me.
Feb 11 '10 #4

P: 1
FYI The whole thing will fail if you have a duplicate key pair. You may want to extend to handle that situation.
Dec 16 '14 #5

P: 1
Here is an open source library http://www.multipetros.gr/public-pro...s/confing-dll/ for ini files read/write. It's very well documented and uses indexers (like a dictionary) to contact with the properties. I suggest to give a try!
May 20 '15 #6