Qual é a maneira mais fácil de analisar um arquivo INI em Java?

Eu estou escrevendo um substituto para um aplicativo legado em Java. Um dos requisitos é que os arquivos ini que o aplicativo antigo utilizasse tivessem que ser lidos como estão no novo aplicativo Java. O formato desses arquivos ini é o estilo comum do windows, com seções de header e pares key = value, usando # como o caractere para comentar.

Eu tentei usar a class Properties do Java, mas é claro que isso não funcionará se houver confrontos de nome entre diferentes headers.

Então a questão é, qual seria a maneira mais fácil de ler neste arquivo INI e acessar as chaves?

A biblioteca que eu usei é ini4j . É leve e analisa os arquivos ini com facilidade. Também não usa dependencies esotéricas para 10.000 outros arquivos jar, já que um dos objectives do design era usar apenas a API Java padrão.

Este é um exemplo de como a biblioteca é usada:

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 mencionado , o ini4j pode ser usado para isso. Deixe-me mostrar um outro exemplo.

Se nós temos um arquivo INI como este:

 [header] key = value 

O seguinte deve exibir value para STDOUT:

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

Confira os tutoriais para mais exemplos.

Tão simples quanto 80 linhas:

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

Aqui está um exemplo simples, mas poderoso, usando a class 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"); } 

A Configuração do Commons possui várias dependencies de tempo de execução . No mínimo, commons-lang e commons-logging são necessários. Dependendo do que você está fazendo com ele, você pode precisar de bibliotecas adicionais (veja o link anterior para detalhes).

Ou com a API Java padrão, você pode usar java.util.Properties :

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

Em 19 linhas, estendendo o java.util.Properties para analisar em várias seções:

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

Outra opção é o Apache Commons Config também tem uma class para o carregamento de arquivos INI . Ele tem algumas dependencies de tempo de execução , mas para arquivos INI ele deve requerer somente collections, lang e logs do Commons.

Eu usei o Commons Config em projetos com suas propriedades e configurações XML. É muito fácil de usar e suporta alguns resources muito poderosos.

Você poderia tentar JINIFile. É uma tradução do TIniFile do Delphi, mas para java

https://github.com/SubZane/JIniFile

Eu pessoalmente prefiro Confucious .

É legal, já que não requer dependencies externas, é pequeno – apenas 16K, e carrega automaticamente o seu arquivo ini na boot. Por exemplo

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