62

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 に変更してもらうには時間がかかるため、既存の形式のままにしておくことをお勧めします。既存のファイルを解析するより。

4

13 に答える 13

49

いいえ、これに対する組み込みのサポートはありません。

独自の「INIFileReader」を作成する必要があります。たぶん、このようなものですか?

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

編集:ポールのコメントを反映するように更新。

于 2009-01-27T22:49:16.567 に答える
18

Java の「.properties」ファイルのほとんどは、「=」がセパレーターであると仮定して分割できますが、形式はそれよりもかなり複雑で、スペース、等号、改行、および任意の Unicode 文字をプロパティ名または値に埋め込むことができます。

C# アプリケーション用の Java プロパティをロードする必要があったため、JavaProperties.cs を実装して、Java バージョンと同じアプローチを使用して「.properties」形式のファイルを正しく読み書きできるようにしました。http://www.kajabityで確認できます。 .com/index.php/2009/06/loading-java-properties-files-in-csharp/ .

そこには、クラスの C# ソースを含む zip ファイルと、私がテストしたいくつかのサンプル プロパティ ファイルがあります。

楽しみ!

于 2009-06-07T17:24:04.580 に答える
17

最終クラス。ありがとう@eXXL

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()
于 2011-10-08T11:05:19.783 に答える
8

ファイル内で空行、アウトコメント、引用を可能にするメソッドを作成しました。

例:

var1="値1"
var2='値2'

'var3=アウトコメント
;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;
}
于 2009-05-14T10:53:28.127 に答える
3

ええ、私が知っているこれを行うための組み込みクラスはありません。

しかし、それは本当に問題になるべきではありませんか?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;
}

使用方法の例を次に示します。

Dictionary<string,string> Properties = GetProperties("data.txt");
Console.WriteLine("Hello: " + Properties["Hello"]);
Console.ReadKey();
于 2009-01-27T22:50:41.837 に答える
2

本当の答えはノーです (少なくともそれだけではありません)。独自のコードを記述してそれを行うこともできます。

于 2012-02-09T22:00:14.573 に答える
1

C#は通常、あなたが言ったように* .iniスタイルのファイルではなく、xmlベースの構成ファイルを使用するため、これを処理するための組み込みはありません。ただし、Google は多くの有望な結果を返します。

于 2009-01-27T22:45:43.530 に答える
1

これを行う組み込みの方法はわかりません。ただし、心配する必要がある区切り文字は改行文字と等号だけなので、簡単に実行できるように思えます。

ファイルの内容を指定して NameValueCollection または IDictionary を返すルーチンを作成するのは非常に簡単です。

于 2009-01-27T22:48:28.347 に答える
1

C# の自動プロパティ構文を既定値と制限付きのセットと共に使用することもできます。ここでの利点は、プロパティ「ファイル」(実際にはクラス) に任意の種類のデータ型を含めることができることです。もう 1 つの利点は、C# プロパティ構文を使用してプロパティを呼び出すことができることです。ただし、これを機能させるには、プロパティごとに数行 (プロパティ宣言に 1 行、コンストラクターに 1 行) が必要です。

using System;
namespace ReportTester {
   class TestProperties
   {
        internal String ReportServerUrl { get; private set; }
        internal TestProperties()
        {
            ReportServerUrl = "http://myhost/ReportServer/ReportExecution2005.asmx?wsdl";
        }
   }
}
于 2011-09-12T19:56:50.307 に答える
0

これはまさにあなたが求めているものではないことを理解していますが、念のため:

実際のJava プロパティ ファイルをロードする場合は、そのエンコーディングに対応する必要があります。 Java ドキュメントでは、エンコーディングが ISO 8859-1 であることが示されています。これには、正しく解釈できない可能性のあるエスケープ シーケンスが含まれています。たとえば、このSOの回答を見て、UTF-8をISO 8859-1に変換するために何が必要かを確認してください(およびその逆)

これを行う必要があるとき、私たちはオープンソースのPropertyFile.csを見つけ、エスケープ シーケンスをサポートするためにいくつかの変更を加えました。このクラスは、読み取り/書き込みのシナリオに適しています。サポートするPropertyFileIterator.csクラスも必要です。

真の Java プロパティをロードしていない場合でも、prop ファイルが保存する必要があるすべての文字を表現できることを確認してください (少なくとも UTF-8)。

于 2010-03-16T20:07:51.747 に答える