Hay una manera fácil en C# para leer un archivo de propiedades que tiene cada propiedad en una línea separada seguido por un signo igual y el valor, tales como los siguientes:

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

En Java, las Propiedades de la clase se encarga de esto analizar fácilmente:

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

Que fácilmente se puede cargar el archivo en C# y analizar cada línea, pero hay una construida en forma fácil de obtener una propiedad sin tener que analizar el nombre de la clave y el signo de igual a mí mismo? El C# información que he encontrado parece siempre a favor de XML, pero este es un archivo existente que no controlo, y prefiero mantenerlo en el formato existente, ya que se requieren más tiempo para conseguir otro equipo para cambiar a XML que analizar el archivo existente.

InformationsquelleAutor Tai Squared | 2009-01-27

14 Comentarios

  1. 40

    No hay ningún soporte integrado para esto.

    Usted tiene que hacer su propio «INIFileReader».
    Tal vez algo como esto?

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

    Edit: Actualizado para reflejar Pablo comentario.

    • es una mala manera si el valor de la propiedad contiene ‘=’
    • He actualizado la respuesta para solucionar ese problema
  2. 18

    La Mayoría De Java «.»propiedades de los archivos se pueden dividir asumiendo el «=» es el separador – pero el formato es mucho más complicado que eso, y permite la incrustación de los espacios, es igual, saltos de línea y cualquier tipo de caracteres Unicode en el nombre de la propiedad o valor.

    Necesitaba para cargar algunas propiedades de Java para una aplicación en C#, así que me han implementado JavaProperties.cs correctamente a leer y escribir «.»propiedades de formato de archivos utilizando el mismo enfoque que en la versión de Java – lo puedes encontrar en http://www.kajabity.com/index.php/2009/06/loading-java-properties-files-in-csharp/.

    Allí, usted encontrará un archivo zip que contiene el código fuente de C# para la clase, y algunos ejemplos de propiedades de archivos que he probado con.

    Disfrutar!

    • Este vínculo es más hasta la fecha kajabity.com/kajabity-tools
    • El código de estas clases es de ahora en GitHub. Enlace para el que está en el sitio principal.
  3. 16

    Final de la clase. Gracias @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 { }
    }
    }
    }
    }

    Ejemplo de uso:

    //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()
    • Muy útil el código, pero me da un error si el archivo de propiedades que ya no existe: el constructor, que llama a reload(), crea el archivo y mantiene un bloqueo sobre el mismo, por lo que el Save() no se puede guardar.
  4. 7

    He escrito un método que permite emty líneas, outcommenting y citando en el archivo.

    Ejemplos:

    var1=»valor1″

    var2=’valor2′

    ‘var3=outcommented

    ;var4=outcommented, demasiado

    Aquí está el método:

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

    Otra respuesta (en enero de 2018) a la vieja pregunta (en enero de 2009).

    La especificación de archivo de propiedades Java se describe en el JavaDoc de java.util.Propiedades.de carga(java.io.El lector). Uno de los problemas es que la especificación es un poco complicado que la primera impresión que podemos tener. Otro problema es que algunas respuestas aquí arbitrariamente adicional especificaciones – por ejemplo, ; y ' son considerados como titulares de las líneas de comentario, pero no debe ser. Doble/solo citas en torno a los valores de la propiedad se quitan, pero no debe ser.

    Los siguientes son puntos a tener en cuenta.

    1. Hay dos tipos de línea, líneas naturales y las líneas lógicas.
    2. Una línea natural se termina por \n, \r, \r\n o el final de la secuencia.
    3. Una línea lógica puede ser extendido a través de varias adyacentes líneas naturales escapando el terminador de línea de secuencia con un carácter de barra diagonal inversa \.
    4. Cualquier espacio en blanco en el inicio de la segunda y siguientes líneas naturales en una línea lógica se descartan.
    5. Espacios en blanco son el espacio (, \u0020), tab (\t, \u0009) y la forma de alimentación (\f, \u000C).
    6. Como se indica explícitamente en la especificación, «no es suficiente con sólo examinar el carácter que precede a un terminador de línea de secuencia para decidir si el terminador de línea se escapó; debe haber un número impar de barras contiguas para el terminador de línea para ser escapado. Desde la entrada se procesan de izquierda a derecha, un no-cero, incluso el número de 2n contiguos barras invertidas antes de un terminador de línea (o en otra parte) codifica n barras diagonales inversas después de escapar de procesamiento.»
    7. = se utiliza como separador entre una clave y un valor.
    8. : se utiliza como separador entre una clave y un valor, también.
    9. El separador entre una clave y un valor puede ser omitido.
    10. Una línea de comentario se ha # o ! como su primer caracteres sin espacios en blanco, lo que significa que conducen los espacios en blanco antes de # o ! están permitidos.
    11. Una línea de comentario no puede ser extendida a la siguiente naturales líneas, incluso su terminador de línea es precedido por \.
    12. Como se indica explícitamente en la especificación, =, : y espacios en blanco que puede ser incrustado en una clave si se escapan por barras diagonales inversas.
    13. Incluso terminador de línea de caracteres se puede incluir el uso de \r y \n secuencias de escape.
    14. Si un valor se omite, una cadena vacía se utiliza como un valor.
    15. \uxxxx se utiliza para representar un carácter Unicode.
    16. Un carácter de barra diagonal inversa antes que un no-válido carácter de escape no es tratado como un error; es silencio cayó.

    Así, por ejemplo, si test.properties tiene el siguiente contenido:

    # 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

    debe ser interpretada como los siguientes pares clave-valor.

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

    PropertiesLoader clase en Authlete.Authlete paquete de NuGet puede interpretar el formato de la especificación. El ejemplo de código siguiente:

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

    generará la siguiente salida:

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

    Un equivalente de ejemplo en Java es la siguiente:

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

    El código fuente, PropertiesLoader.cs, se puede encontrar en authlete-csharp. xUnit pruebas para PropertiesLoader están escritos en PropertiesLoaderTest.cs.

  6. 2

    Sí, no hay en clases para hacer esto, que yo sepa.

    Pero que no debe ser una cuestión que se debe esto? Parece bastante fácil de analizar sólo almacenando el resultado de Stream.ReadToEnd() en una cadena, la división basada en las nuevas líneas y, a continuación, dividir cada registro en la = carácter. Lo que te queda es un montón de claves los pares de valores que se puede echar en un diccionario.

    He aquí un ejemplo que podría funcionar para usted:

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

    He aquí un ejemplo de cómo usarlo:

    Dictionary<string,string> Properties = GetProperties("data.txt");
    Console.WriteLine("Hello: " + Properties["Hello"]);
    Console.ReadKey();
    • si se reemplaza «\n» con ‘\n’ no necesitamos .ToCharArray()
    • tal vez su código es necesario para mejorar, para manejar las líneas de comentarios que comienzan con #, y también otros caracteres vacíos, como key = value, los espacios en blanco deben ser eliminados.
  7. 1

    No sé de cualquier manera integrada de hacer esto. Sin embargo, parece bastante fácil de hacer, ya que la única delimitadores usted tiene que preocuparse el carácter de nueva línea y el signo igual.

    Sería muy fácil escribir una rutina que devolverá un NameValueCollection, o un IDictionary dado el contenido del archivo.

  8. 1

    También puede utilizar C# automática de sintaxis de las propiedades con valores por defecto y una restrictiva conjunto. La ventaja aquí es que se puede tener cualquier tipo de tipo de datos en sus propiedades «archivo» (en realidad una clase). La otra ventaja es que se puede utilizar C# de la propiedad sintaxis para invocar las propiedades. Sin embargo, usted sólo necesita un par de líneas para cada propiedad (uno en la declaración de propiedad y uno en el constructor) para hacer este trabajo.

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

    Me doy cuenta de que esto no es exactamente lo que estás preguntando, pero sólo en caso de:

    Cuando se desea cargar un real archivo de propiedades Java, tendrá que acomodar su codificación. El Java docs indican que la codificación es el ISO 8859-1, que contiene algunas secuencias de escape que no puede interpretar correctamente. Por ejemplo mira este MODO de respuesta a ver lo que es necesario a su vez de UTF-8 a ISO 8859-1 (y viceversa)

    Cuando necesitábamos hacer esto, hemos encontrado un open-source PropertyFile.cs y hecho un par de cambios para apoyar las secuencias de escape. Esta clase es un buen lugar para leer/escribir los escenarios. Usted necesitará el apoyo de PropertyFileIterator.cs clase.

    Incluso si no estás de carga verdadero Java propiedades, asegúrese de que su proposición de archivo puede expresar todos los caracteres que usted necesita para guardar (UTF-8, al menos)

  10. 0

    No es la solución exacta de lo que quiere. por favor, encontrar el artículo de aquí

    su código tiene un montón de puntos fuertes en cuanto a la eficiencia.

    1. La aplicación no se carga el archivo de texto en cada solicitud. Es
      carga el archivo de texto de una sola vez a la memoria. Para la posterior
      solicitud, devuelve directamente el valor de la memoria. Esto es mucho
      más eficiente si el archivo de texto contiene miles o más
      los pares clave-valor.
    2. Cualquier cambio en el archivo de texto no requiere reiniciar la aplicación. Un
      archivo system watcher ha sido usada para registrar el archivo de estado.
      En caso de cambios, se desencadena un evento y las cargas de los nuevos cambios
      de acuerdo a la memoria, por lo que, puede cambiar el archivo de texto en uno
      aplicación/editor de texto y ver el cambio en efecto en la web
      aplicación.
    3. Que no sólo son capaces de utilizarlo en una aplicación web, pero también capaz de
      para su uso en cualquier aplicación de escritorio.

    Gracias. Que tengan un buen día.

    • Por desgracia, el código ha sido eliminado.
  11. 0

    No no existe : Pero he creado una sencilla clase para ayudar a :

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

    Espero que esto ayude.

Dejar respuesta

Please enter your comment!
Please enter your name here