Existe-t-il un moyen simple en C # de lire un fichier de propriétés contenant chaque propriété sur une ligne distincte suivie d'un signe égal et de la valeur, comme suit:
ServerName=prod-srv1
Port=8888
CustomProperty=Any value
En Java, la classe Properties gère facilement cette analyse:
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"));
Je peux facilement charger le fichier en C # et analyser chaque ligne, mais existe-t-il un moyen intégré pour obtenir facilement une propriété sans avoir à analyser le nom de clé et le signe égal à signer moi-même? Les informations C # que j'ai trouvées semblent toujours privilégier XML, mais il s'agit d'un fichier existant que je ne contrôle pas et que je préférerais conserver dans son format actuel, car il faudra plus de temps pour demander à une autre équipe de le changer en XML. que l'analyse du fichier existant.
Non, il n'y a pas de support intégré pour cela.
Vous devez créer votre propre "INIFileReader". Peut-être quelque chose comme ça?
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: mis à jour pour refléter le commentaire de Paul.
La plupart des fichiers Java ".properties" peuvent être scindés en supposant que "=" est le séparateur - mais le format est beaucoup plus compliqué que cela et permet l’incorporation d’espaces, d’égal, de nouvelle ligne et de tout caractère Unicode dans le nom ou la valeur de la propriété.
J'avais besoin de charger certaines propriétés Java pour une application C # et j'ai donc implémenté JavaProperties.cs pour lire et écrire correctement les fichiers au format ".properties" en utilisant la même approche que la version Java - vous pouvez le trouver à l'adresse http: // www. .kajabity.com/index.php/2009/06/loading-Java-properties-files-in-csharp/ .
Vous y trouverez un fichier Zip contenant la source C # de la classe et des exemples de fichiers de propriétés avec lesquels je l’ai testé.
Prendre plaisir!
Classe finale. Merci @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 { }
}
}
}
}
Exemple d'utilisation:
//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()
J'ai écrit une méthode qui permet de créer des lignes, de dépasser les citations et de les citer dans le fichier.
Exemples:
var1 = "valeur1"
var2 = 'valeur2'
'var3 = dépassé
.__; var4 = dépassé aussi
Voici la méthode:
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;
}
Encore une autre réponse (en janvier 2018) à l'ancienne question (en janvier 2009).
La spécification du fichier de propriétés Java est décrite dans le JavaDoc de Java.util.Properties.load(Java.io.Reader)
. Un problème est que la spécification est un peu compliquée que la première impression que nous pouvons avoir. Un autre problème est que certaines réponses ici ont ajouté des spécifications supplémentaires de manière arbitraire - par exemple, ;
et '
sont considérés comme des débuts de lignes de commentaire, mais ils ne devraient pas l'être. Les citations doubles/simples autour des valeurs de propriété sont supprimées, mais elles ne devraient pas l'être.
Les points suivants sont à prendre en compte.
\n
, \r
, \r\n
ou la fin du flux.\
.
, \u0020
), l'onglet (\t
, \u0009
) et le flux de formulaire (\f
, \u000C
).=
sert de séparateur entre une clé et une valeur.:
sert également de séparateur entre une clé et une valeur.#
ou !
en tant que son premier caractère d'espacement non blanc, ce qui signifie que les espaces avant le début de #
ou !
sont autorisés.\
.=
, :
et des espaces blancs peuvent être incorporés dans une clé s'ils sont masqués par des barres obliques inverses.\r
et \n
.\uxxxx
est utilisé pour représenter un caractère Unicode.Ainsi, par exemple, si test.properties
a le contenu suivant:
# 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
il devrait être interprété comme les paires clé-valeur suivantes.
+------+--------------------+
| KEY | VALUE |
+------+--------------------+
| key1 | value1 |
| key2 | value2 |
| key3 | value3 |
| key4 | value4 |
| key5 | value5 |
| key6 | value6 |
| : = | \colon\space\equal |
+------+--------------------+
PropertiesLoader
class dans Le paquet Authlete.Authlete NuGet peut interpréter le format de la spécification. L'exemple de code ci-dessous:
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}");
}
}
}
}
va générer cette sortie:
key1 = value1
key2 = value2
key3 = value3
key4 = value4
key5 = value5
key6 = value6
: = = \colon\space\equal
Un exemple équivalent en Java est le suivant:
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());
}
}
}
Le code source, PropertiesLoader.cs
, se trouve dans authlete-csharp . xUnit tests pour PropertiesLoader
sont écrits en PropertiesLoaderTest.cs
.
Oui, je ne suis au courant d'aucune classe intégrée.
Mais cela ne devrait pas vraiment être un problème, non? Il semble assez facile d'analyser simplement en stockant le résultat de Stream.ReadToEnd()
dans une chaîne, en le divisant en fonction de nouvelles lignes, puis en divisant chaque enregistrement sur le caractère =
. Ce qui vous reste, c'est un tas de paires de valeurs clés que vous pouvez facilement mélanger dans un dictionnaire.
Voici un exemple qui pourrait fonctionner pour vous:
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;
}
Voici un exemple d'utilisation:
Dictionary<string,string> Properties = GetProperties("data.txt");
Console.WriteLine("Hello: " + Properties["Hello"]);
Console.ReadKey();
La vraie réponse est non (du moins pas par elle-même). Vous pouvez toujours écrire votre propre code pour le faire.
C # utilise généralement des fichiers de configuration basés sur XML plutôt que le fichier de style * .ini comme vous l'avez dit, il n'y a donc rien de intégré pour gérer cela. Cependant, Google renvoie un nombre de résultats prometteurs .
Je ne connais aucun moyen intégré de faire cela. Cependant, cela semblerait assez facile à faire, puisque les seuls délimiteurs à prendre en compte sont le caractère de nouvelle ligne et le signe égal.
Il serait très facile d'écrire une routine qui renverra un NameValueCollection ou un IDictionary en fonction du contenu du fichier.
Vous pouvez également utiliser la syntaxe de propriété automatique C # avec des valeurs par défaut et un ensemble restrictif. L'avantage ici est que vous pouvez avoir n'importe quel type de données dans vos propriétés "fichier" (maintenant une classe). L’autre avantage est que vous pouvez utiliser la syntaxe de propriété C # pour appeler les propriétés. Cependant, vous avez juste besoin de quelques lignes pour chaque propriété (une dans la déclaration de propriété et une dans le constructeur) pour que cela fonctionne.
using System;
namespace ReportTester {
class TestProperties
{
internal String ReportServerUrl { get; private set; }
internal TestProperties()
{
ReportServerUrl = "http://myhost/ReportServer/ReportExecution2005.asmx?wsdl";
}
}
}
Il existe plusieurs packages NuGet pour cela, mais tous sont actuellement en version préliminaire.
[Mise à jour] À compter de juin 2018, Capgemini.Cauldron.Core.JavaProperties est maintenant dans une version stable (versions 2.1.0 et 3.0.20).
Non, il n'y en a pas: mais j'ai créé une classe facile pour vous aider:
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");
}
}
}
J'espère que cela t'aides.
Je réalise que ce n'est pas exactement ce que vous demandez, mais juste au cas où:
Lorsque vous souhaitez charger un fichier de propriétés Java actual, vous devez adapter son codage. Les documents Java indiquent que le codage est ISO 8859-1, qui contient des séquences d'échappement que vous pourriez ne pas interpréter correctement. Par exemple, regardez cette réponse SO pour voir ce qui est nécessaire pour convertir l'UTF-8 en ISO 8859-1 (et vice versa)
Lorsque nous avons eu besoin de faire cela, nous avons trouvé un fichier open-source PropertyFile.cs et apporté quelques modifications pour prendre en charge les séquences d'échappement. Cette classe convient bien aux scénarios de lecture/écriture. Vous aurez également besoin de la classe PropertyFileIterator.cs class.
Même si vous ne chargez pas de vraies propriétés Java, assurez-vous que votre fichier prop peut exprimer tous les caractères que vous avez besoin de sauvegarder (au moins UTF-8).
Il y a la solution exacte de ce que vous voulez. s'il vous plaît trouver l'article de ici
son code a un tas de points forts en matière d'efficacité.
Merci. Bonne journée.