Domanda

Sto scrivendo un sostituto drop-in per un'applicazione legacy in Java. Uno dei requisiti è che i file ini utilizzati dall'applicazione precedente devono essere letti così come sono nella nuova applicazione Java. Il formato di questo file ini è lo stile comune di Windows, con sezioni di intestazione e coppie chiave = valore, usando # come carattere per commentare.

Ho provato ad usare la classe Properties da Java, ma ovviamente non funzionerà se ci sono conflitti di nomi tra intestazioni diverse.

Quindi la domanda è: quale sarebbe il modo più semplice per leggere in questo file INI e accedere alle chiavi?

È stato utile?

Soluzione

La libreria che ho usato è ini4j . È leggero e analizza facilmente i file ini. Inoltre non utilizza dipendenze esoteriche da altri 10.000 file jar, poiché uno degli obiettivi di progettazione era utilizzare solo l'API Java standard

Questo è un esempio di come viene utilizzata la libreria:

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

Altri suggerimenti

Come menzionato , ini4j può essere usato per raggiungere questo obiettivo. Lascia che ti mostri un altro esempio.

Se abbiamo un file INI come questo:

[header]
key = value

Quanto segue dovrebbe visualizzare value su STDOUT:

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

Controlla i tutorial per altri esempi.

Semplice come 80 righe:

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

Ecco un esempio semplice ma potente, usando 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");
}

Commons Configuration ha una serie di dipendenze di runtime . Come minimo, commons-lang e commons-logging sono obbligatori. A seconda di cosa ci fai, potresti aver bisogno di librerie aggiuntive (vedi il link precedente per i dettagli).

O con l'API Java standard è possibile utilizzare java .util.Properties :

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

In 18 righe, estendendo java.util.Properties per analizzare in più sezioni:

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

Un'altra opzione è Apache Commons Config ha anche una classe per il caricamento da file INI . Ha alcune dipendenze di runtime , ma per i file INI dovrebbe richiedere solo raccolte Commons, lang e registrazione.

Ho usato Commons Config nei progetti con le loro proprietà e configurazioni XML. È molto facile da usare e supporta alcune funzionalità piuttosto potenti.

Potresti provare JINIFile. È una traduzione del TIniFile di Delphi, ma per java

https://github.com/SubZane/JIniFile

Preferisco di persona Confucious .

È bello, poiché non richiede dipendenze esterne, è minuscolo - solo 16K e carica automaticamente il file ini all'inizializzazione. Per es.

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

È semplice come questo .....

//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");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top