Lire le fichier de propriétés Java en C #

** Introduction **

Stack Overflow a une question _ «Est-ce que .NET peut charger et analyser un fichier de propriétés équivalent à la classe Propriétés Java?» (janvier 2009) _ Je demande comment lire le fichier de propriétés en C #. Il existe des cas comme le questionneur qui souhaite lire le fichier de propriétés existant tel quel en C # sans apporter de modifications.

Il y a des réponses codées à la question, mais aucune des implémentations n'est pratique, sauf ma réponse. .. Certains ajoutent même des spécifications qui n'existent pas. Traitez ; et comme des caractères de début de ligne de commentaire et supprimez les guillemets entourant les valeurs de propriété.

Après tout, il n'y a pas d'autre choix que de le fabriquer vous-même.

** Spécifications du fichier de propriétés **

La spécification du fichier de propriétés Java est [java.util.Properties.load (java.io.Reader)](https://docs.oracle.com/javase/9/docs/api/java/util/Properties. Il est écrit en JavaDoc de html # load-java.io.Reader-) </ code>. Le problème est que les spécifications sont un peu plus compliquées que vous ne l'imaginez. Bien que non exhaustifs, les points suivants doivent être considérés en particulier.

  1. Il existe deux types de lignes: natural line et logical line.
  2. Les lignes naturelles sont séparées par «\ n», «\ r», «\ r \ n» ou à la fin du flux.
  3. Une ligne logique peut s'étendre sur plusieurs lignes naturelles adjacentes en échappant la séquence de terminaison de ligne avec une barre oblique inverse.
  4. Les caractères vides au début de la deuxième ligne naturelle et les suivantes de la ligne logique sont supprimés.
  5. Les caractères vides sont des espaces (``, \ u0020), des tabulations ( \ t, \ u0009) et des sauts de ligne ( \ f, \ u000C).
  6. Comme indiqué explicitement dans la spécification, _ "Pour déterminer si un terminateur de ligne est échappé, il ne suffit pas de regarder le caractère avant la séquence de fin de ligne, car le terminateur de ligne est échappé. Doit avoir une série de barres obliques inverses impaires. L'entrée est traitée de gauche à droite, il y a donc 2n barres obliques inverses (paires non nulles) avant (ou ailleurs) le terminateur de ligne. S'il est présent, n antislashs seront encodés après l'échappement. "_
  7. = est utilisé comme séparateur clé / valeur.
  8. : Est également utilisé comme séparateur clé / valeur.
  9. Le délimiteur entre la clé et la valeur est facultatif.
  10. La ligne de commentaire a «#» ou «!» Comme premier caractère non vide. Autrement dit, les caractères vides avant «#» et «!» Sont autorisés.
  11. L'échappement des terminateurs de ligne avec des barres obliques inverses ne permet pas aux lignes de commentaire de s'étendre sur plusieurs lignes.
  12. Comme indiqué explicitement dans la spécification, =, : et les caractères vides peuvent également être incorporés dans la clé en les échappant avec une barre oblique inverse.
  13. Des terminaisons de ligne paires peuvent être incluses en utilisant les séquences d'échappement «\ r» et «\ n».
  14. Si la valeur est omise, traitez-la comme une chaîne de caractères vide.
  15. \ uxxxx représente le caractère Unicode.
  16. Les backslashes placés avant les caractères qui ne constituent pas un caractère d'échappement valide ne sont pas traités comme une erreur et sont simplement supprimés.

** Exemples de fichier de propriétés **

C'est pourquoi, 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 doit être interprété comme le groupe de paires clé-valeur suivant.

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

** Exemple de code **

NuGet La classe PropertiesLoader contenue dans le package" Authlete.Authlete "est le fichier Properties. Peut interpréter les spécifications de. L'exemple de code suivant

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

Produit la sortie suivante.

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

Voici un code similaire en Java:

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

Code source

Le code source de PropertiesLoader.cs </ code> est authlete-csharp Il existe dans (: //github.com/authlete/authlete-csharp). De plus, le groupe de test xUnit pour PropertiesLoader est [PropertiesLoaderTest.cs](https://github.com/authlete/authlete-csharp/blob/ Il est décrit dans master / Authlete.Tests / Util / PropertiesLoaderTest.cs) </ code>.

Recommended Posts