views:

8673

answers:

9

Is there an easy way in C# to read a properties file that has each property on a separate line followed by an equals sign and the value, such as the following:

ServerName=prod-srv1
Port=8888
CustomProperty=Any value

In Java, the Properties class handles this parsing easily:

Properties myProperties=new Properties();
FileInputStream fis = new FileInputStream (new File("CustomProps.properties"));
myProperties.load(fis);
System.out.println(myProperties.getProperty("ServerName"));
System.out.println(myProperties.getProperty("CustomProperty"));

I can easily load the file in C# and parse each line, but is there a built in way to easily get a property without having to parse out the key name and equals sign myself? The C# information I have found seems to always favor XML, but this is an existing file that I don't control and I would prefer to keep it in the existing format as it will require more time to get another team to change it to XML than parsing the existing file.

+1  A: 

C# generally uses xml-based config files rather than the *.ini-style file like you said, so there's nothing built-in to handle this. However, google returns a number of promising results.

Joel Coehoorn
A: 

I don't know of any built-in way to do this. However, it would seem easy enough to do, since the only delimiters you have to worry about are the newline character and the equals sign.

It would be very easy to write a routine that will return a NameValueCollection, or an IDictionary given the contents of the file.

casperOne
+3  A: 

No there is no built-in support for this.

You have to make your own "INIFileReader". Maybe something like this?

var data = new Dictionary<string, string>();
foreach (var row in File.ReadAllLines(PATH_TO_FILE))
  data.Add(row.Split('=')[0], row.Split('=')[1]);

Console.WriteLine(data["ServerName"]);
Jesper Palm
A: 

Yeah there's no built in classes to do this that I'm aware of.

But that shouldn't really be an issue should it? It looks easy enough to parse just by storing the result of Stream.ReadToEnd() in a string, splitting based on new lines and then splitting each record on the = character. What you'd be left with is a bunch of key value pairs which you can easily toss into a dictionary.

Here's an example that might work for you:

public static Dictionary<string, string> GetProperties(string path)
{
    string fileData = "";
    using (StreamReader sr = new StreamReader(path))
    {
        fileData = sr.ReadToEnd().Replace("\r", "");
    }
    Dictionary<string, string> Properties = new Dictionary<string, string>();
    string[] kvp;
    string[] records = fileData.Split("\n".ToCharArray());
    foreach (string record in records)
    {
        kvp = record.Split("=".ToCharArray());
        Properties.Add(kvp[0], kvp[1]);
    }
    return Properties;
}

Here's an example of how to use it:

Dictionary<string,string> Properties = GetProperties("data.txt");
Console.WriteLine("Hello: " + Properties["Hello"]);
Console.ReadKey();
Spencer Ruport
if you replace "\n" with '\n' you won't need the .ToCharArray()
Matthew Whited
A: 

There are a few examples of a PropertyBag class on the web which can do this, e.g. this one.

AdamRalph
+2  A: 

I've written a method that allows emty lines, outcommenting and quoting within the file.

Examples:

var1="value1"
var2='value2'

'var3=outcommented
;var4=outcommented, too

Here's the method:

public static IDictionary ReadDictionaryFile(string fileName)
{
    Dictionary<string, string> dictionary = new Dictionary<string, string>();
    foreach (string line in File.ReadAllLines(fileName))
    {
        if ((!string.IsNullOrEmpty(line)) &&
            (!line.StartsWith(";")) &&
            (!line.StartsWith("#")) &&
            (!line.StartsWith("'")) &&
            (line.Contains('=')))
        {
            int index = line.IndexOf('=');
            string key = line.Substring(0, index).Trim();
            string value = line.Substring(index + 1).Trim();

            if ((value.StartsWith("\"") && value.EndsWith("\"")) ||
                (value.StartsWith("'") && value.EndsWith("'")))
            {
                value = value.Substring(1, value.Length - 2);
            }
            dictionary.Add(key, value);
        }
    }

    return dictionary;
}
eXXL
+5  A: 

Most Java ".properties" files can be split by assuming the "=" is the separator - but the format is significantly more complicated than that and allows for embedding spaces, equals, newlines and any Unicode characters in either the property name or value.

I needed to load some Java properties for a C# application so I have implemented JavaProperties.cs to correctly read and write ".properties" formatted files using the same approach as the Java version - you can find it at http://www.kajabity.com/index.php/2009/06/loading-java-properties-files-in-csharp/.

There, you will find a zip file containing the C# source for the class and some sample properties files I tested it with.

Enjoy!

A: 

I use a smiliar approach to the one above. Worth noting that some C# compilers will complain that you dont have a function header that includes the key, value type.

public static IDictionary ReadDictionaryFile(string fileName)

Thanks!

NPike
@NPike: please read the FAQ (http://stackoverflow.com/faq). This is not a discussion forum, and what you posted is not an answer to the question.
John Saunders
A: 

I realize that this isn't exactly what you're asking, but just in case:

When you want to load an actual Java properties file, you'll need to accomodate its encoding. The Java docs indicate that the encoding is ISO 8859-1, which contains some escape sequences that you might not correctly interpret. For instance look at this SO answer to see what's necessary to turn UTF-8 into ISO 8859-1 (and vice versa)

When we needed to do this, we found an open-source PropertyFile.cs and made a few changes to support the escape sequences. This class is a good one for read/write scenarios. You'll need the supporting PropertyFileIterator.cs class as well.

Even if you're not loading true Java properties, make sure that your prop file can express all the characters you need to save (UTF-8 at least)

Steve Eisner