Kann .NET eine Eigenschaften laden und analysieren, die der Java -Eigenschaftenklasse entsprechen?

StackOverflow https://stackoverflow.com/questions/485659

Frage

Gibt es eine einfache Möglichkeit in C#, eine Eigenschaftendatei zu lesen, die jede Eigenschaft in einer separaten Zeile hat, gefolgt von einem Gleichen Zeichen und dem Wert, wie der folgenden:

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

In Java behandelt die Eigenschaftenklasse dieses Parsen leicht:

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

Ich kann die Datei leicht in C# laden und jede Zeile analysieren, aber gibt es eine integrierte Möglichkeit, um einfach eine Eigenschaft zu erhalten, ohne den Schlüsselnamen analysieren zu müssen und selbst zu signieren? Die C# -Informationen, die ich gefunden habe, scheint immer XML zu bevorzugen, aber dies ist eine vorhandene Datei, die ich nicht kontrolliere, und ich würde es vorziehen, sie im vorhandenen Format zu behalten, da mehr Zeit erforderlich ist, um ein anderes Team in XML zu ändern als die vorhandene Datei zu analysieren.

War es hilfreich?

Lösung

Nein, es gibt keine integrierte Unterstützung dafür.

Sie müssen Ihr eigenes "Inifilereader" machen. Vielleicht so etwas?

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

Bearbeiten: Aktualisiert, um Pauls Kommentar widerzuspiegeln.

Andere Tipps

Die meisten Java ".Properties" -Dateien können durch Annahme des "=" -Szentrums aufgeteilt werden - das Format ist jedoch erheblich komplizierter als das und ermöglicht ein Einbettungsbereich, gleiche, neue Linien und alle Unicode -Zeichen im Eigenschaftsnamen oder im Eigenschaftsnamen oder im Eigenschaft.

Ich musste einige Java -Eigenschaften für eine C# -Anwendung laden, damit ich Javaproperties.cs implementiert habe http://www.kajabity.com/index.php/2009/06/loading-java-properties-files-in-csharp/.

Dort finden Sie eine ZIP -Datei, die die C# Quelle für die Klasse und einige Beispiel -Eigenschaftendateien enthält, mit denen ich sie getestet habe.

Genießen!

Letzte Klasse. Vielen Dank @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 { }
            }
        }
    }


}

Probengebrauch:

//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()

Ich habe eine Methode geschrieben, die EMty -Zeilen ermöglicht, die in der Datei ausgegeben und zitiert.

Beispiele:

var1 = "value1"
var2 = 'value2' '

'var3 = optimented
; var4 = optimiert auch,

Hier ist die Methode:

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;
}

Noch eine Antwort (im Januar 2018) auf die alte Frage (im Januar 2009).

Die Spezifikation der Java -Eigenschaftendatei wird im Javadoc von beschrieben java.util.properties.load (java.io.reader). Ein Problem ist, dass die Spezifikation etwas kompliziert ist als der erste Eindruck, den wir möglicherweise haben. Ein weiteres Problem ist, dass einige Antworten hier willkürlich zusätzliche Spezifikationen hinzugefügt haben - zum Beispiel, ; und ' werden als Starter von Kommentaren angesehen, aber sie sollten es nicht sein. Doppel-/einzelne Zitate rund um Eigenschaftswerte werden entfernt, sollten es jedoch nicht sein.

Die folgenden sind Punkte zu berücksichtigen.

  1. Es gibt zwei Arten von Linien, natürliche Linien und logische Linien.
  2. Eine natürliche Linie wird von beendet von \n, \r, \r\n oder das Ende des Stroms.
  3. Eine logische Linie kann über mehrere benachbarte natürliche Linien verteilt werden \.
  4. Jeder weiße Raum zu Beginn der zweiten und folgen natürlichen Linien in einer logischen Linie wird verworfen.
  5. Weiße Räume sind Raum (, \u0020), Tab (\t, \u0009) und Form Feed (\f, \u000C).
  6. Wie ausdrücklich in der Spezifikation angegeben, "Es reicht nicht aus, nur das Zeichen vor einer Linien -Terminator -Sequenz zu untersuchen, um zu entscheiden, ob der Leitungs -Terminator entkommen ist. Es muss eine seltsame Anzahl an zusammenhängender Rückflächen für den zu entkommenen Leitungs -Terminator bestehen. Da der Eingang von links nach rechts verarbeitet wird , eine ungleich Null-Anzahl von 2n-zusammenhängenden Rückflächen, bevor ein Linien-Terminator (oder anderswo) n Backslashs nach der Fluchtverarbeitung codiert. "
  7. = wird als Trennzeichen zwischen einem Schlüssel und einem Wert verwendet.
  8. : wird auch als Trennzeichen zwischen einem Schlüssel und einem Wert verwendet.
  9. Der Trennzeichen zwischen einem Schlüssel und einem Wert kann weggelassen werden.
  10. Eine Kommentarzeile hat # oder ! Als erste nicht-weiße Raumfiguren, was bedeutet # oder ! sind erlaubt.
  11. Eine Kommentarlinie kann nicht auf die nächsten natürlichen Linien ausgedehnt werden, selbst wenn ihr Linien -Terminator vorangegangen ist \.
  12. Wie ausdrücklich in der Spezifikation angegeben, =, : und weiße Räume können in einen Schlüssel eingebettet werden, wenn sie durch Backslashes entkommen werden.
  13. Sogar Zeilen -Terminator -Zeichen können verwendet werden \r und \n Fluchtsequenzen.
  14. Wenn ein Wert weggelassen wird, wird eine leere Zeichenfolge als Wert verwendet.
  15. \uxxxx wird verwendet, um ein Unicode -Zeichen darzustellen.
  16. Ein Backslash-Charakter, bevor ein nicht-valid-Fluchtcharakter nicht als Fehler behandelt wird; Es wird stillschweigend fallen gelassen.

Also zum Beispiel, wenn test.properties hat den folgenden Inhalt:

# 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

Es sollte als folgende Schlüsselwertpaare interpretiert werden.

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

PropertiesLoader Klasse in AuthLete.Authlete Das Nuget -Paket kann das Format der Spezifikation interpretieren. Der Beispielcode unten:

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

generiert diese Ausgabe:

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

Ein gleichwertiges Beispiel in Java lautet wie folgt:

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());
        }    
    }
}

Der Quellcode, Propertiesloader.cs, kann gefunden werden in AuthLe-CSharp. Xunit Tests für PropertiesLoader sind geschrieben PropertiesloadTest.cs.

Ja, es gibt keinen integrierten Unterricht, um dies zu tun, von denen ich weiß.

Aber das sollte nicht wirklich ein Problem sein, sollte es? Es sieht einfach genug an, wenn man das Ergebnis speichert Stream.ReadToEnd() In einer Zeichenfolge, die auf neuen Zeilen aufgeteilt und dann jeden Datensatz auf dem Aufteilen ist = Charakter. Was Sie übrig bleiben würden, sind eine Reihe von Schlüsselwertpaaren, die Sie leicht in ein Wörterbuch werfen können.

Hier ist ein Beispiel, das möglicherweise für Sie funktioniert:

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;
}

Hier ist ein Beispiel dafür, wie man es benutzt:

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

Die wirkliche Antwort lautet nein (zumindest nicht für sich). Sie können immer noch Ihren eigenen Code schreiben.

C# verwendet im Allgemeinen XML-basierte Konfigurationsdateien anstelle der Datei im *.ini-Stil, wie Sie gesagt haben. Daher ist nichts integriert, um dies zu verarbeiten. Google gibt jedoch a zurück Anzahl vielversprechender Ergebnisse.

Ich kenne keine eingebaute Möglichkeit, dies zu tun. Es scheint jedoch leicht genug zu sein, da die einzigen Grenzwerte, über die Sie sich Sorgen machen müssen, der Newline -Charakter und das Equals -Zeichen sind.

Es wäre sehr einfach, eine Routine zu schreiben, die eine nameValuecollection zurückgibt, oder ein Idectionary mit dem Inhalt der Datei.

Sie können auch C# Automatische Eigenschaftssyntax mit Standardwerten und einem restriktiven Satz verwenden. Der Vorteil hierfür ist, dass Sie dann über irgendeine Art von Datentyp in Ihrer Eigenschaften "Datei" (jetzt tatsächlich eine Klasse) verfügen können. Der andere Vorteil ist, dass Sie die C# -Stax -Syntax verwenden können, um die Eigenschaften aufzurufen. Sie benötigen jedoch nur ein paar Zeilen für jede Eigenschaft (eine in der Immobilienerklärung und eine im Konstruktor), um diese Arbeit zu machen.

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

Dafür gibt es mehrere Nuget-Pakete, aber alle befinden sich derzeit in der Vorabversion.

Update] Ab Juni 2018, Capgemini.cauldron.core.javaproperties ist jetzt in einer stabilen Version (Version 2.1.0 und 3.0.20).

Mir ist klar, dass dies nicht genau das ist, was Sie fragen, sondern nur für den Fall:

Wenn Sie eine laden möchten tatsächlich Java Properties -Datei, Sie müssen seine Codierung unterbringen. Die Java -Dokumente Geben Sie an, dass die Codierung ISO 8859-1 ist, die einige Fluchtsequenzen enthält, die Sie möglicherweise nicht richtig interpretieren. Zum Beispiel ansehen Diese Antwort Um zu sehen, was erforderlich ist, um UTF-8 in ISO 8859-1 zu machen (und umgekehrt)

Wenn wir dies tun mussten, fanden wir eine Open-Source PropertyFile.cs und nahm einige Änderungen vor, um die Escape -Sequenzen zu unterstützen. Diese Klasse ist gut für Lesen/Schreibszenarien. Sie benötigen die Unterstützung PropertyFileiterator.cs Klasse auch.

Auch wenn Sie keine echten Java-Eigenschaften laden, stellen Sie sicher, dass Ihre Prop-Datei alle Zeichen, die Sie speichern müssen, ausdrücken können (UTF-8 mindestens).

Es gibt genau die Lösung dessen, was Sie wollen. Bitte finden Sie den Artikel von hier

Sein Code hat eine Reihe starker Punkte in Bezug auf Effizienz.

  1. Die Anwendung lädt die Textdatei nicht in jeder Anfrage. Es lädt die Textdatei nur einmal in den Speicher. Für die nachfolgende Anfrage wird der Wert direkt aus dem Speicher zurückgegeben. Dies ist viel effizienter, wenn Ihre Textdatei Tausende oder mehr Schlüsselwertpaare enthält.
  2. Eine Änderung in der Textdatei erfordert keinen Neustart von Anwendungen. Ein Dateisystembeobachter wurde verwendet, um den Dateistatus zu verfolgen. Wenn es sich ändert, löst es ein Ereignis aus und lädt die neuen Änderungen entsprechend dem Speicher, sodass Sie die Textdatei in einer Anwendung/einem Texteditor ändern und den geänderten Effekt in der Webanwendung sehen können.
  3. Sie können es nicht nur in einer Webanwendung verwenden, sondern auch in jeder Desktop -Anwendung verwenden.

Vielen Dank. Einen schönen Tag noch.

Nein, es gibt nicht: Aber ich habe eine einfache Klasse geschaffen, um zu helfen:

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

    }
}

Hoffe das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top