Question

J'écris une solution de remplacement pour une application héritée en Java. L'une des conditions est que les fichiers ini utilisés par l'ancienne application doivent être lus tels quels dans la nouvelle application Java. Le format de ces fichiers ini correspond au style Windows habituel, avec des sections d’en-tête et des paires clé = valeur, avec # comme caractère de commentaire.

J'ai essayé d'utiliser la classe Properties de Java, mais cela ne fonctionnera bien sûr pas en cas de conflit de noms entre différents en-têtes.

La question est donc de savoir quel serait le moyen le plus facile de lire ce fichier INI et d’accéder aux clés.

Était-ce utile?

La solution

La bibliothèque que j'ai utilisée est ini4j . Il est léger et analyse facilement les fichiers ini. En outre, il n’utilise pas de dépendances ésotériques pour 10 000 autres fichiers jar, l’un des objectifs de la conception étant d’utiliser uniquement l’API Java standard.

Voici un exemple d'utilisation de la bibliothèque:

Ini ini = new Ini(new File(filename));
java.util.prefs.Preferences prefs = new IniPreferences(ini);
System.out.println("grumpy/homePage: " + prefs.node("grumpy").get("homePage", null));

Autres conseils

Comme mentionné dans , ini4j peut être utilisé à cette fin. Laissez-moi vous montrer un autre exemple.

Si nous avons un fichier INI comme celui-ci:

[header]
key = value

Ce qui suit devrait afficher valeur dans STDOUT:

Ini ini = new Ini(new File("/path/to/file"));
System.out.println(ini.get("header", "key"));

Consultez les didacticiels pour plus d'exemples.

Aussi simple que 80 lignes:

package windows.prefs;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IniFile {

   private Pattern  _section  = Pattern.compile( "\\s*\\[([^]]*)\\]\\s*" );
   private Pattern  _keyValue = Pattern.compile( "\\s*([^=]*)=(.*)" );
   private Map< String,
      Map< String,
         String >>  _entries  = new HashMap<>();

   public IniFile( String path ) throws IOException {
      load( path );
   }

   public void load( String path ) throws IOException {
      try( BufferedReader br = new BufferedReader( new FileReader( path ))) {
         String line;
         String section = null;
         while(( line = br.readLine()) != null ) {
            Matcher m = _section.matcher( line );
            if( m.matches()) {
               section = m.group( 1 ).trim();
            }
            else if( section != null ) {
               m = _keyValue.matcher( line );
               if( m.matches()) {
                  String key   = m.group( 1 ).trim();
                  String value = m.group( 2 ).trim();
                  Map< String, String > kv = _entries.get( section );
                  if( kv == null ) {
                     _entries.put( section, kv = new HashMap<>());   
                  }
                  kv.put( key, value );
               }
            }
         }
      }
   }

   public String getString( String section, String key, String defaultvalue ) {
      Map< String, String > kv = _entries.get( section );
      if( kv == null ) {
         return defaultvalue;
      }
      return kv.get( key );
   }

   public int getInt( String section, String key, int defaultvalue ) {
      Map< String, String > kv = _entries.get( section );
      if( kv == null ) {
         return defaultvalue;
      }
      return Integer.parseInt( kv.get( key ));
   }

   public float getFloat( String section, String key, float defaultvalue ) {
      Map< String, String > kv = _entries.get( section );
      if( kv == null ) {
         return defaultvalue;
      }
      return Float.parseFloat( kv.get( key ));
   }

   public double getDouble( String section, String key, double defaultvalue ) {
      Map< String, String > kv = _entries.get( section );
      if( kv == null ) {
         return defaultvalue;
      }
      return Double.parseDouble( kv.get( key ));
   }
}

Voici un exemple simple mais puissant, utilisant la classe apache HierarchicalINIConfiguration :

HierarchicalINIConfiguration iniConfObj = new HierarchicalINIConfiguration(iniFile); 

// Get Section names in ini file     
Set setOfSections = iniConfObj.getSections();
Iterator sectionNames = setOfSections.iterator();

while(sectionNames.hasNext()){

 String sectionName = sectionNames.next().toString();

 SubnodeConfiguration sObj = iniObj.getSection(sectionName);
 Iterator it1 =   sObj.getKeys();

    while (it1.hasNext()) {
    // Get element
    Object key = it1.next();
    System.out.print("Key " + key.toString() +  " Value " +  
                     sObj.getString(key.toString()) + "\n");
}
La

Configuration commune comporte un certain nombre de dépendances d'exécution . Au minimum, commons-lang et commons-logging est requis. Selon votre utilisation, vous aurez peut-être besoin de bibliothèques supplémentaires (voir le lien précédent pour plus de détails).

Ou avec les API Java standard, vous pouvez utiliser java .util.Properties :

Properties props = new Properties();
try (FileInputStream in = new FileInputStream(path)) {
    props.load(in);
}

En 18 lignes, extension du java.util.Properties à analyser en plusieurs sections:

public static Map<String, Properties> parseINI(Reader reader) throws IOException {
    Map<String, Properties> result = new HashMap();
    new Properties() {

        private Properties section;

        @Override
        public Object put(Object key, Object value) {
            String header = (((String) key) + " " + value).trim();
            if (header.startsWith("[") && header.endsWith("]"))
                return result.put(header.substring(1, header.length() - 1), 
                        section = new Properties());
            else
                return section.put(key, value);
        }

    }.load(reader);
    return result;
}

Une autre option est Apache Commons Config a également une classe à charger à partir de fichiers INI . Il possède des dépendances d'exécution , mais pour les fichiers INI, il ne doit nécessiter que des collections communes, lang et la journalisation.

J'ai utilisé Commons Config sur des projets avec leurs propriétés et leurs configurations XML. Il est très facile à utiliser et supporte des fonctionnalités assez puissantes.

Vous pouvez essayer JINIFile. Est une traduction du TIniFile de Delphi, mais pour Java

https://github.com/SubZane/JIniFile

Personnellement, je préfère Confucious .

C'est bien, car il ne nécessite aucune dépendance externe, il est minuscule - seulement 16 Ko et charge automatiquement votre fichier ini à l'initialisation. Ex.

Configurable config = Configuration.getInstance();  
String host = config.getStringValue("host");   
int port = config.getIntValue("port"); 
new Connection(host, port);

C’est aussi simple que cela .....

//import java.io.FileInputStream;
//import java.io.FileInputStream;

Properties prop = new Properties();
//c:\\myapp\\config.ini is the location of the ini file
//ini file should look like host=localhost
prop.load(new FileInputStream("c:\\myapp\\config.ini"));
String host = prop.getProperty("host");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top