-
Apr 18th, 2024, 02:02 PM
#1
Thread Starter
Fanatic Member
Windows INI Reader and Writer v1.3
Hi here is an update of my ini reader and writer I made a few years back, anyway I been working on a new project and needed a few other things from my ini so I added them in hope you like it Comments welcome.
INI Class
Code:
/* Simple INI file reading and writing class.
* Version 1.0
* By Ben a.k.a DreamVB
* Please use this class as you want.
*
* Update v1.2 18/4/2024
* Added support to read and write Multiline Strings
* Added support to read and write integer
* Added support to read and write bool
* Added support to read and write double
* Added SelectionExists
* Added KeyExists
*
* Update v1.3 22/4/2024
* Some changes with error checking thanks for the info PlausiblyDamp
* Added check if value exists.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace inidemo
{
class inifile
{
private readonly FileInfo fi;
[DllImport("kernel32")]
static extern long WritePrivateProfileString(string Section, string Key, string Value, string FilePath);
[DllImport("kernel32")]
static extern int GetPrivateProfileString(string Section, string Key, string Default, StringBuilder RetVal, int Size, string FilePath);
public void WriteString(string selection, string Key, string Value)
{
WritePrivateProfileString(selection, Key, Value, fi.FullName);
}
public string ReadString(string selection, string Key, string vDefault = "")
{
StringBuilder sb = new StringBuilder(2048);
//Get INI file.
GetPrivateProfileString(selection, Key, vDefault, sb, 2048, fi.FullName);
//Return value.
return sb.ToString();
}
public void WriteMultilineString(string selection,string Key, string Value)
{
string S = Value.Replace(Environment.NewLine, "\\n");
WriteString(selection, Key, S);
}
public void WriteInteger(string selection,string Key, int Value)
{
WriteString(selection, Key, Value.ToString());
}
public void WriteBool(string selection, string Key, bool Value)
{
WriteString(selection, Key, Value.ToString());
}
public void WriteDouble(string selection, string Key, double Value)
{
WriteString(selection, Key, Value.ToString());
}
public int ReadInteger(string selection, string Key, int vDefault)
{
if (int.TryParse(ReadString(selection, Key, vDefault.ToString()), out int v))
{
return v;
}
else
{
return vDefault;
}
}
public string ReadMultilineString(string selection, string Key, string vDefault)
{
string v;
try
{
v = ReadString(selection, Key, vDefault.ToString()).Replace("\\n", Environment.NewLine);
}catch (Exception e)
{
throw new ApplicationException("ApplicationException", e);
}
return v;
}
public bool ReadBool(string selection, string Key, bool vDefault)
{
if (bool.TryParse(ReadString(selection, Key, vDefault.ToString()), out bool v))
{
return v;
}
else
{
return vDefault;
}
}
public double ReadDouble(string selection, string Key, double vDefault)
{
if (double.TryParse(ReadString(selection, Key, vDefault.ToString()), out double v))
{
return v;
}
else
{
return vDefault;
}
}
public void DeleteSelection(string selection)
{
WritePrivateProfileString(selection, null, null, fi.FullName);
}
public void DeleteKey(string selection, string key)
{
WritePrivateProfileString(selection, key, null, fi.FullName);
}
public List<string> ReadSelections()
{
List<string> temp = new List<string>();
string sLine;
if (!fi.Exists)
{
return temp;
}
using (StreamReader sr = new StreamReader(fi.FullName))
{
while (!sr.EndOfStream)
{
//Get and trim line
sLine = sr.ReadLine();
//Check for opening and closing tags
if (sLine.StartsWith("[") && (sLine.EndsWith("]")))
{
//Add to collection.
temp.Add(sLine.Substring(1, sLine.Length - 2));
}
}
//close file
sr.Close();
}
return temp;
}
public bool SelectionExists(string selection)
{
List<string> Temp;
bool Found = false;
try
{
Temp = ReadSelections();
foreach(string s in Temp)
{
if (s.ToLower() == selection.ToLower())
{
Found = true;
break;
}
}
}catch (Exception e)
{
throw new Exception(e.Message);
}
Temp.Clear();
return Found;
}
public bool KeyExists(string selection, string Key)
{
List<string> Temp;
bool Found = false;
try
{
Temp = ReadSelectionKeys(selection);
foreach (string s in Temp)
{
if (s.ToLower() == Key.ToLower())
{
Found = true;
break;
}
}
}
catch (Exception e)
{
throw new ApplicationException("ApplicationException", e);
}
Temp.Clear();
return Found;
}
public bool ValueExists(string selection, string key, string value)
{
return ReadString(selection, key, string.Empty) == value;
}
public List<string> ReadSelectionKeys(string selection)
{
List<string> temp = new List<string>();
string sLine;
string SelName = string.Empty;
if (!fi.Exists)
{
return temp;
}
using (StreamReader sr = new StreamReader(fi.FullName))
{
while (!sr.EndOfStream)
{
//Get and trim line
sLine = sr.ReadLine();
//Check for opening and closing tags
if (sLine.StartsWith("[") && (sLine.EndsWith("]")))
{
//Add to collection.
SelName = sLine.Substring(1, sLine.Length - 2);
if (!sr.EndOfStream)
{
//Get next line
sLine = sr.ReadLine();
}
}
//Compare selection names.
if (SelName.ToUpper() == selection.ToUpper())
{
if (sLine.Length > 0)
{
int pos = sLine.IndexOf("=");
//Check for equals sign
if (pos > 0)
{
//Extract key
temp.Add(sLine.Remove(pos, sLine.Length - pos));
}
}
}
}
//Close file.
sr.Close();
}
return temp;
}
public inifile(string Filename)
{
fi = new FileInfo(Filename);
}
}
}
Last edited by BenJones; Apr 22nd, 2024 at 03:08 PM.
Reason: Updated code
-
Apr 22nd, 2024, 12:26 PM
#2
Re: Windows INI Reader and Writer
Just a couple of points...
Firstly I wouldn't do this
Code:
private static FileInfo fi;
as the static keyword means only one instance of the fi variable exists and it is shared between all instances of the inifile class in your application. That means if you try to use the class to manipulate two (or more) different inifiles then whichever one you use last will be the only one you modify. e.g. try the following snippet
Code:
var i1 = new inifile("test1.ini");
var i2 = new inifile("test2.ini");
i1.WriteBool("section1", "key1", true);
i2.WriteBool("section1", "key1", false);
i1.WriteString("section1", "key2", "Hello World");
In that case nothing would be written to test1.ini, only test2.ini - removing the keyword static would solve this problem.
It might be beneficial to mark fi as readonly however.
Secondly, if you are going to just catch and rethrow an Exception like
Code:
//....
catch (Exception e)
{
throw new Exception(e.Message);
}
return v;
then you may as well just not catch the exception, all you are doing is throwing away things like the stack trace which might be useful to higher level code. Either just let the Exception propagate up and the callers can deal with it, or wrap it in another exception e.g.
Code:
//....
catch (Exception e)
{
throw new ApplicationException("Your error message", e);
}
return v;
I would personally just let the Exception propagate up the call stack.
In fact on the ReadXXXX methods it might be better to use the various TryParse methods e.g.
Code:
public int ReadInteger(string selection, string Key, int vDefault)
{
if (int.TryParse(ReadString(selection, Key, vDefault.ToString()), out int v))
{
return v;
}
else
{
return vDefault; // or throw an exception
}
}
Finally, although this is possibly personal preference, it might be worth considering overloading the various Write methods so you have a single Write e.g.
Code:
public void Write(string selection, string key, int value)
{
WriteString(selection, key, value.ToString());
}
public void Write(string selection, string key, bool value)
{
WriteString(selection, key, value.ToString());
}
-
Apr 22nd, 2024, 01:17 PM
#3
Thread Starter
Fanatic Member
Re: Windows INI Reader and Writer
Thanks for the suggestions PlausiblyDamp I look into updating the class again.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|