Can .NET load and parse a properties file equivalent to Java Properties class?

前端 未结 13 1630
死守一世寂寞
死守一世寂寞 2020-12-01 01:19

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:



        
相关标签:
13条回答
  • 2020-12-01 01:43

    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.

    0 讨论(0)
  • 2020-12-01 01:45

    No there is not : But I have created one easy class to help :

    public class PropertiesUtility
    {
        private static Hashtable ht = new Hashtable();
        public void loadProperties(string path)
        {
            string[] lines = System.IO.File.ReadAllLines(path);
            bool readFlag = false;
            foreach (string line in lines)
            {
                string text = Regex.Replace(line, @"\s+", "");
                readFlag =  checkSyntax(text);
                if (readFlag)
                {
                    string[] splitText = text.Split('=');
                    ht.Add(splitText[0].ToLower(), splitText[1]);
                }
            }
        }
    
        private bool checkSyntax(string line)
        {
            if (String.IsNullOrEmpty(line) || line[0].Equals('['))
            {
                return false;
            }
    
            if (line.Contains("=") && !String.IsNullOrEmpty(line.Split('=')[0]) && !String.IsNullOrEmpty(line.Split('=')[1]))
            {
                return true;
            }
            else
            {
                throw new Exception("Can not Parse Properties file please verify the syntax");
            }
        }
    
        public string getProperty(string key)
        {
            if (ht.Contains(key))
            {
                return ht[key].ToString();
            }
            else
            {
                throw new Exception("Property:" + key + "Does not exist");
            }
    
        }
    }
    

    Hope this helps.

    0 讨论(0)
  • 2020-12-01 01:50

    Yet another answer (in January 2018) to the old question (in January 2009).

    The specification of Java properties file is described in the JavaDoc of java.util.Properties.load(java.io.Reader). One problem is that the specification is a bit complicated than the first impression we may have. Another problem is that some answers here arbitrarily added extra specifications - for example, ; and ' are regarded as starters of comment lines but they should not be. Double/single quotations around property values are removed but they should not be.

    The following are points to be considered.

    1. There are two kinds of line, natural lines and logical lines.
    2. A natural line is terminated by \n, \r, \r\n or the end of the stream.
    3. A logical line may be spread out across several adjacent natural lines by escaping the line terminator sequence with a backslash character \.
    4. Any white space at the start of the second and following natural lines in a logical line are discarded.
    5. White spaces are space (, \u0020), tab (\t, \u0009) and form feed (\f, \u000C).
    6. As stated explicitly in the specification, "it is not sufficient to only examine the character preceding a line terminator sequence to decide if the line terminator is escaped; there must be an odd number of contiguous backslashes for the line terminator to be escaped. Since the input is processed from left to right, a non-zero even number of 2n contiguous backslashes before a line terminator (or elsewhere) encodes n backslashes after escape processing."
    7. = is used as the separator between a key and a value.
    8. : is used as the separator between a key and a value, too.
    9. The separator between a key and a value can be omitted.
    10. A comment line has # or ! as its first non-white space characters, meaning leading white spaces before # or ! are allowed.
    11. A comment line cannot be extended to next natural lines even its line terminator is preceded by \.
    12. As stated explicitly in the specification, =, : and white spaces can be embedded in a key if they are escaped by backslashes.
    13. Even line terminator characters can be included using \r and \n escape sequences.
    14. If a value is omitted, an empty string is used as a value.
    15. \uxxxx is used to represent a Unicode character.
    16. A backslash character before a non-valid escape character is not treated as an error; it is silently dropped.

    So, for example, if test.properties has the following content:

    # A comment line that starts with '#'.
       # This is a comment line having leading white spaces.
    ! A comment line that starts with '!'.
    
    key1=value1
      key2 : value2
        key3 value3
    key\
      4=value\
        4
    \u006B\u0065\u00795=\u0076\u0061\u006c\u0075\u00655
    \k\e\y\6=\v\a\lu\e\6
    
    \:\ \= = \\colon\\space\\equal
    

    it should be interpreted as the following key-value pairs.

    +------+--------------------+
    | KEY  | VALUE              |
    +------+--------------------+
    | key1 | value1             |
    | key2 | value2             |
    | key3 | value3             |
    | key4 | value4             |
    | key5 | value5             |
    | key6 | value6             |
    | : =  | \colon\space\equal |
    +------+--------------------+
    

    PropertiesLoader class in Authlete.Authlete NuGet package can interpret the format of the specification. The example code below:

    using System;
    using System.IO;
    using System.Collections.Generic;
    using Authlete.Util;
    
    namespace MyApp
    {
        class Program
        {
            public static void Main(string[] args)
            {
                string file = "test.properties";
                IDictionary<string, string> properties;
    
                using (TextReader reader = new StreamReader(file))
                {
                    properties = PropertiesLoader.Load(reader);
                }
    
                foreach (var entry in properties)
                {
                    Console.WriteLine($"{entry.Key} = {entry.Value}");
                }
            }
        }
    }
    

    will generate this output:

    key1 = value1
    key2 = value2
    key3 = value3
    key4 = value4
    key5 = value5
    key6 = value6
    : = = \colon\space\equal
    

    An equivalent example in Java is as follows:

    import java.util.*;
    import java.io.*;
    
    public class Program
    {
        public static void main(String[] args) throws IOException
        {
            String file = "test.properties";
            Properties properties = new Properties();
    
            try (Reader reader = new FileReader(file))
            {
                 properties.load(reader);
            }
    
            for (Map.Entry<Object, Object> entry : properties.entrySet())
            {
                System.out.format("%s = %s\n", entry.getKey(), entry.getValue());
            }    
        }
    }
    

    The source code, PropertiesLoader.cs, can be found in authlete-csharp. xUnit tests for PropertiesLoader are written in PropertiesLoaderTest.cs.

    0 讨论(0)
  • 2020-12-01 01:51

    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();
    
    0 讨论(0)
  • 2020-12-01 01:55

    The real answer is no (at least not by itself). You can still write your own code to do it.

    0 讨论(0)
  • 2020-12-01 02:03

    You can also use C# automatic property syntax with default values and a restrictive set. The advantage here is that you can then have any kind of data type in your properties "file" (now actually a class). The other advantage is that you can use C# property syntax to invoke the properties. However, you just need a couple of lines for each property (one in the property declaration and one in the constructor) to make this work.

    using System;
    namespace ReportTester {
       class TestProperties
       {
            internal String ReportServerUrl { get; private set; }
            internal TestProperties()
            {
                ReportServerUrl = "http://myhost/ReportServer/ReportExecution2005.asmx?wsdl";
            }
       }
    }
    
    0 讨论(0)
提交回复
热议问题