¿Cuál es la forma más fácil de analizar un archivo INI en Java?

Estoy escribiendo un reemplazo directo para una aplicación heredada en Java. Uno de los requisitos es que los archivos ini que utilizó la aplicación anterior se deben leer tal cual en la nueva aplicación Java. El formato de estos archivos ini es el estilo de ventana común, con secciones de encabezado y pares clave = valor, usando # como el carácter para comentar.

Intenté usar la clase de Propiedades de Java, pero, por supuesto, eso no funcionará si hay conflictos de nombres entre diferentes encabezados.

Entonces la pregunta es, ¿cuál sería la forma más fácil de leer en este archivo INI y acceder a las claves?

La biblioteca que he usado es ini4j . Es liviano y analiza los archivos ini con facilidad. Además, no usa dependencias esotéricas para otros 10.000 archivos jar, ya que uno de los objectives del diseño era utilizar solo la API Java estándar.

Este es un ejemplo de cómo se usa la biblioteca:

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

Como se mencionó , ini4j se puede usar para lograr esto. Déjame mostrar otro ejemplo.

Si tenemos un archivo INI como este:

 [header] key = value 

Lo siguiente debe mostrar value a STDOUT:

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

Consulte los tutoriales para ver más ejemplos.

Tan simple como 80 líneas:

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

Aquí hay un ejemplo simple pero potente, que utiliza la clase 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 configuración de Commons tiene varias dependencias de tiempo de ejecución . Como mínimo, se requiere el uso de commons-lang y commons-logging . Dependiendo de lo que esté haciendo con él, es posible que necesite bibliotecas adicionales (consulte el enlace anterior para obtener más información).

O con la API estándar de Java puede usar java.util.Properties :

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

En 19 líneas, se extienden las java.util.Properties para analizar en múltiples secciones:

 public static Map parseINI(Reader reader) throws IOException { Map 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("]")) result.put(header.substring(1, header.length() - 1), section = new Properties()); else section.put(key, value); return null; } }.load(reader); return result; } 

Otra opción es Apache Commons Config también tiene una clase para cargar archivos INI . Tiene algunas dependencias de tiempo de ejecución , pero para los archivos INI solo debería requerir colecciones Commons, lang y logging.

He usado Commons Config en proyectos con sus propiedades y configuraciones XML. Es muy fácil de usar y admite algunas funciones bastante potentes.

Puedes probar JINIFile. Es una traducción de TIniFile de Delphi, pero para java

https://github.com/SubZane/JIniFile

Personalmente prefiero Confucious .

Es agradable, ya que no requiere ninguna dependencia externa, es pequeña, solo 16K, y carga automáticamente su archivo ini en la inicialización. P.ej

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