Fast Reading and Writing of Configuration Files

Environment: Configuration Files, INIs

This is similar to the article published by Ayende Rahien on A C# Configuration File Reader that doesn't use the Win32 API function. The only difference is that this code is quick and doesn't depend on the data in the memory for a long time because the configuration file might be used or changed by some other application before the application process it. So, the following code just reads the file sequentially and, when it finds the section or key, takes the action and closes the file then and there itself. The drawback of this operation is that every time you call the function, it will open the file and close it with or without modifying. That's a tradeoff for making sure that the configuration file is reflecting changes once the function is completed.

using System;
using System.IO;
using System.Collections.Specialized;

namespace IniMgr
{
   public class IniTask
   {
      public static void SetIniString(string sFile, string Sec,
                                      string Key, string Val)
      {
         StreamReader sr = null;
         string newLineChars = "\r\n";    // define newline chars.

         // But find the default new line chars from the
         // System.IO.TextWriter
         if(true)
         {
            StringWriter tw = new StringWriter();
            newLineChars    = tw.NewLine;
         }

         string slines = null;
         if (File.Exists(sFile))
         {
            bool reWrite = false;
            using ( sr = new StreamReader(sFile))
            {
               String line;
               bool foundSection = false;
               while ((line = sr.ReadLine()) != null)
               {
                  line = line.Trim();
                  if(line.Length > 1)
                  {
                     if(line[0] == '[')
                     {
                        int end = line.IndexOf("]");
                        if(end != -1)
                        {
                           string section = line.Substring(1,
                                                           end-1);
                           if(String.Compare(section,Sec,true)==0)
                           {
                              foundSection = true;
                              slines += line + newLineChars;
                              continue;
                           }
                           else
                           {
                              if(foundSection == true)
                              {
                                 // we did not find our key,
                                 // so we add one
                                 slines += Key + "=" + Val
                                               + newLineChars;;
                                 slines += line + newLineChars;
                                 line    = sr.ReadToEnd();
                                 slines += line;
                                 reWrite = true;
                                 break;
                              }
                           }
                        }
                     }
                     if(foundSection == true)
                     {
                        string [] pair = line.Split('=');
                        if(pair.Length > 1)
                        {
                           if(String.Compare(pair[0], Key,true)
                                     == 0)
                           {
                              line = Key + "=" + Val
                                               + newLineChars;
                              slines += line;
                              line    = sr.ReadToEnd();
                              slines += line;
                              reWrite = true;
                              break;
                           }
                        }
                     }
                  }
                  slines += line + newLineChars;
               }
               if(foundSection == false)
               {
                  slines += "[" + Sec + "]" + newLineChars;
                  slines += Key + "=" + Val  + newLineChars;
                  reWrite = true;
               }
               if(foundSection == true && reWrite == false)
               {
                  slines += Key + "=" + Val  + newLineChars;
                  reWrite = true;
               }
            }
            if( reWrite == true)
            {
               using (StreamWriter sw = new StreamWriter(sFile))
               {
                  sw.Write(slines);
               }
            }
         }
         else
         {
            slines = "[" + Sec + "]" + newLineChars;
            slines += Key + "=" + Val  + newLineChars;
            using (StreamWriter sw = new StreamWriter(sFile))
            {
               sw.Write(slines);
            }

         }
      }
      public static string GetIniString(string sFile, string Sec,
                                        string Key, string Val)
      {
         StreamReader sr = null;
         if (File.Exists(sFile))
         {
            using ( sr = new StreamReader(sFile))
            {
               String line;
               // Read and display lines from the file until
               // the end of the file is reached.
               bool foundSection = false;
               while ((line = sr.ReadLine()) != null)
               {
                  line = line.Trim();
                  if(line.Length > 1)
                  {
                     if(line[0] == '[')
                     {
                        int end = line.IndexOf("]");
                        if(end != -1)
                        {
                           string section = line.Substring(1,
                                                           end-1);
                           if(String.Compare(section, Sec, true)
                              == 0)
                           {
                              foundSection = true;
                              continue;
                           }
                           else
                              foundSection = false;
                        }
                     }
                     if(foundSection == true)
                     {
                        string [] pair = line.Split('=');
                        if(pair.Length > 1)
                        {
                           if(String.Compare(pair[0], Key, true)
                               == 0)
                           {
                              Val = pair[1];
                              break;
                           }
                        }
                     }
                  }
               }
            }
         }
         return Val;
      }
      // some extra functions
      public static StringCollection GetSections(string sFile)
      {
         StreamReader sr       = null;
         StringCollection myAL = new StringCollection();
         if (File.Exists(sFile))
         {

            using ( sr = new StreamReader(sFile)) 
            {
               String line;
               // Read and display lines from the file until the
               // end of the file is reached.
               while ((line = sr.ReadLine()) != null)
               {
                  line = line.Trim();
                  if(line.Length > 1)
                  {
                     if(line[0] == '[')
                     {
                        int end = line.IndexOf("]");
                        if(end != -1)
                        {
                           string section = line.Substring(1,
                                                           end-1);
                           myAL.Add(section);
                        }
                     }
                  }
               }
            }
         }
         return myAL;
      }
      public static StringCollection GetSectionKeys(string sFile,
                                                    string Sec)
      {
         StreamReader sr = null;
         StringCollection myAL = new StringCollection();
         if (File.Exists(sFile))
         {
            using ( sr = new StreamReader(sFile)) 
            {
               String line;
               // Read and display lines from the file until
               // the end of the file is reached.
               bool foundSection = false;
               while ((line = sr.ReadLine()) != null)
               {
                  line = line.Trim();
                  if(line.Length > 1)
                  {
                     if(line[0] == '[')
                     {
                        int end = line.IndexOf("]");
                        if(end != -1)
                        {
                           string section = line.Substring(1,
                                                           end-1);
                           if(String.Compare(section, Sec, true)
                              == 0)
                           {
                              foundSection = true;
                              continue;
                           }
                           else
                           {
                              if(foundSection == true)
                              {
                                 break;
                              }
                              foundSection = false;
                           }
                        }
                     }
                     if(foundSection == true)
                     {
                        string [] pair = line.Split('=');
                        if(pair.Length > 1)
                        {
                           myAL.Add(pair[0]);
                        }
                     }
                  }
               }
            }
         }
         return myAL;
      }
   }
}

For simplicity, this code doesn't have error checks.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • CentreCorp is a fully integrated and diversified property management and real estate service company, specializing in the "shopping center" segment, and is one of the premier retail service providers in North America. Company executives travel a great deal, carrying a number of traveling laptops with critical current business data, and no easy way to back up to the network outside the office. Read this case study to learn how CentreCorp implemented a suite of business continuity services that included …

Most Popular Programming Stories

More for Developers

RSS Feeds