C# NET是否可以加载和解析相当于Java属性类的属性文件?

C# NET是否可以加载和解析相当于Java属性类的属性文件?,c#,configuration,file-io,load,C#,Configuration,File Io,Load,在C#中是否有一种简单的方法可以读取一个属性文件,该文件的每个属性都在一行上,后跟一个等号和值,例如: ServerName=prod-srv1 Port=8888 CustomProperty=Any value 在Java中,Properties类可以轻松地处理此解析: Properties myProperties=new Properties(); FileInputStream fis = new FileInputStream (new File("CustomProps.prop

在C#中是否有一种简单的方法可以读取一个属性文件,该文件的每个属性都在一行上,后跟一个等号和值,例如:

ServerName=prod-srv1
Port=8888
CustomProperty=Any value
在Java中,Properties类可以轻松地处理此解析:

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"));

我可以轻松地用C#加载文件并解析每一行,但是是否有一种内置的方法可以轻松地获取属性,而不必自己解析密钥名和等号?我发现的C#信息似乎总是倾向于XML,但这是一个我无法控制的现有文件,我更愿意将其保留为现有格式,因为这需要更多的时间让另一个团队将其更改为XML,而不是解析现有文件。

C#通常使用基于XML的配置文件,而不是像您所说的*.ini样式的文件,因此没有内置的处理方法。然而,google返回了一个。

我不知道有什么内置的方法可以做到这一点。然而,这似乎很容易做到,因为您需要担心的唯一分隔符是换行符和等号


编写一个例程来返回NameValueCollection或给定文件内容的IDictionary将非常容易。

不,没有内置的支持

您必须制作自己的“InFileReader”。 也许是这样的

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

Console.WriteLine(data["ServerName"]);
var data=newdictionary();
foreach(File.ReadAllLines中的var行(路径到文件))
data.Add(row.Split('=')[0],string.Join(“=”,row.Split('=')).Skip(1.ToArray());
Console.WriteLine(数据[“服务器名]);

编辑:更新以反映Paul的评论

是的,据我所知,没有内置类来完成这项工作

但这不应该是个问题,对吗?只需将
Stream.ReadToEnd()
的结果存储在一个字符串中,根据新行进行拆分,然后拆分
=
字符上的每条记录,就可以轻松地进行解析。剩下的是一堆键值对,你可以很容易地把它们放到字典里

下面是一个可能适合您的示例:

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;
}
公共静态字典GetProperties(字符串路径)
{
字符串fileData=“”;
使用(StreamReader sr=新StreamReader(路径))
{
fileData=sr.ReadToEnd().Replace(“\r”,”);
}
字典属性=新字典();
字符串[]kvp;
string[]records=fileData.Split(“\n”.ToCharArray());
foreach(记录中的字符串记录)
{
kvp=record.Split(“=”.ToCharArray());
添加(kvp[0],kvp[1]);
}
归还财产;
}
下面是一个如何使用它的示例:

Dictionary<string,string> Properties = GetProperties("data.txt");
Console.WriteLine("Hello: " + Properties["Hello"]);
Console.ReadKey();
Dictionary Properties=GetProperties(“data.txt”);
WriteLine(“Hello:+Properties[“Hello”]);
Console.ReadKey();

我编写了一个方法,允许在文件中使用多行、多注释和引用

示例:

var1=“value1”
var2='value2'

'var3=outcommented
;var4=也被评论过

方法如下:

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;
}
公共静态IDictionary ReadDictionaryFile(字符串文件名)
{
字典=新字典();
foreach(文件中的字符串行。ReadAllLines(文件名))
{
if((!string.IsNullOrEmpty(line))&&
(!line.StartsWith(“;”))&&
(!line.StartsWith(“#”)&&
(!line.StartsWith(“'))&&
(行包含('='))
{
int index=line.IndexOf('=');
string key=line.Substring(0,index.Trim();
字符串值=line.Substring(索引+1.Trim();
if((value.StartsWith(“\”)和&value.EndsWith(“\”))||
(value.StartsWith(“”)和value.EndsWith(“”))
{
value=value.Substring(1,value.Length-2);
}
添加(键、值);
}
}
返回字典;
}
大多数Java“.properties”文件都可以通过假设“=”是分隔符来分割,但格式要比这复杂得多,允许在属性名称或值中嵌入空格、等号、换行符和任何Unicode字符

我需要为C#应用程序加载一些Java属性,因此我实现了JavaProperties.cs,以便使用与Java版本相同的方法正确读取和写入“.properties”格式的文件-您可以在中找到它

在那里,您将找到一个zip文件,其中包含该类的C#源代码以及我测试该类时使用的一些示例属性文件


享受吧

我意识到这并不是你想要的,只是以防万一:

当您想要加载一个实际的Java属性文件时,您需要适应它的编码。指示编码为ISO 8859-1,其中包含一些可能无法正确解释的转义序列。例如,查看将UTF-8转换为ISO 8859-1所需的内容(反之亦然)

当我们需要这样做时,我们找到了一个开源软件,并做了一些修改以支持转义序列。这个类对于读/写场景来说是一个很好的类。你也需要支持课程

即使您没有加载真正的Java属性,也要确保您的prop文件可以表达所有需要保存的字符(至少是UTF-8)

您还可以使用带有默认值和限制集的C#自动属性语法。这里的优点是,您可以在属性“文件”(现在实际上是一个类)中拥有任何类型的数据类型。另一个优点是可以使用C#属性语法来调用属性。但是,您只需要为每个属性(一个在属性声明中,一个在构造函数中)设置几行代码就可以实现这一点

using System;
namespace ReportTester {
   class TestProperties
   {
        internal String ReportServerUrl { get; private set; }
        internal TestProperties()
        {
            ReportServerUrl = "http://myhost/ReportServer/ReportExecution2005.asmx?wsdl";
        }
   }
}
最后一节课。谢谢

真正的答案是否定的(至少不是它本身)。您仍然可以编写自己的代码来完成此任务。

这是对旧问题(2009年1月)的另一个答案(2018年1月)

Java属性文件的规范在JavaDocO中描述
public class Properties
{
    private Dictionary<String, String> list;
    private String filename;

    public Properties(String file)
    {
        reload(file);
    }

    public String get(String field, String defValue)
    {
        return (get(field) == null) ? (defValue) : (get(field));
    }
    public String get(String field)
    {
        return (list.ContainsKey(field))?(list[field]):(null);
    }

    public void set(String field, Object value)
    {
        if (!list.ContainsKey(field))
            list.Add(field, value.ToString());
        else
            list[field] = value.ToString();
    }

    public void Save()
    {
        Save(this.filename);
    }

    public void Save(String filename)
    {
        this.filename = filename;

        if (!System.IO.File.Exists(filename))
            System.IO.File.Create(filename);

        System.IO.StreamWriter file = new System.IO.StreamWriter(filename);

        foreach(String prop in list.Keys.ToArray())
            if (!String.IsNullOrWhiteSpace(list[prop]))
                file.WriteLine(prop + "=" + list[prop]);

        file.Close();
    }

    public void reload()
    {
        reload(this.filename);
    }

    public void reload(String filename)
    {
        this.filename = filename;
        list = new Dictionary<String, String>();

        if (System.IO.File.Exists(filename))
            loadFromFile(filename);
        else
            System.IO.File.Create(filename);
    }

    private void loadFromFile(String file)
    {
        foreach (String line in System.IO.File.ReadAllLines(file))
        {
            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);
                }

                try
                {
                    //ignore dublicates
                    list.Add(key, value);
                }
                catch { }
            }
        }
    }


}
//load
Properties config = new Properties(fileConfig);
//get value whith default value
com_port.Text = config.get("com_port", "1");
//set value
config.set("com_port", com_port.Text);
//save
config.Save()
# 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
+------+--------------------+
| KEY  | VALUE              |
+------+--------------------+
| key1 | value1             |
| key2 | value2             |
| key3 | value3             |
| key4 | value4             |
| key5 | value5             |
| key6 | value6             |
| : =  | \colon\space\equal |
+------+--------------------+
key1 = value1
key2 = value2
key3 = value3
key4 = value4
key5 = value5
key6 = value6
: = = \colon\space\equal
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");
        }

    }
}