Qual é a maneira mais fácil de analisar um arquivo INI em Java?
Pergunta
Eu estou escrevendo um substituto para um aplicativo herdado em Java. Um dos requisitos é que os arquivos ini que o aplicativo mais antigo utilizadas têm de ser lido como está na nova aplicação Java. O formato desta ini é o estilo de janelas comum, com seções de cabeçalho e chave = valor pares, usando # como o personagem para comentar.
Eu tentei usar a classe Properties Java, mas é claro que não vai funcionar se houver conflitos de nomes entre diferentes cabeçalhos.
Então a questão é, qual seria a maneira mais fácil de ler neste arquivo INI e acesso as chaves?
Solução
A biblioteca que usei é ini4j . É leve e analisa os arquivos ini com facilidade. Além disso ele usa nenhuma dependência esotéricos 10.000 outros arquivos JAR, como um dos objetivos do projeto era usar somente a API Java padrão
Este é um exemplo de como a biblioteca é utilizada:
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));
Outras dicas
Como mencionado , ini4j pode ser usado para alcançar este objectivo. Deixe-me mostrar um outro exemplo.
Se tivermos um arquivo INI assim:
[header]
key = value
A seguir deve exibir value
para STDOUT:
Ini ini = new Ini(new File("/path/to/file"));
System.out.println(ini.get("header", "key"));
Verifique os tutoriais para mais exemplos.
tão simples como 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 simples, mas poderoso exemplo, usando a 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");
}
Configuração Commons tem um número de runtime dependências . No mínimo, commons-lang e commons-logging são obrigatórios. Dependendo do que você está fazendo com ele, você pode exigir bibliotecas adicionais (ver link anterior para detalhes).
Ou com o padrão Java API você pode usar java .util.Properties :
Properties props = new Properties();
try (FileInputStream in = new FileInputStream(path)) {
props.load(in);
}
18 linhas, que se estende a java.util.Properties
para analisar em várias secções:
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;
}
Outra opção é Apache Commons configuração também tem uma classe para o carregamento de INI arquivos . Ele tem alguns runtime dependências , mas para arquivos INI só deve exigir coleções Commons, lang, e registro.
Eu usei Commons configuração em projetos com suas propriedades e configurações XML. É muito fácil de usar e suporta algumas características bastante poderosas.
Você poderia tentar JINIFile. É uma tradução do TIniFile da Delphi, mas para java
Eu, pessoalmente, prefiro Confucious .
É bom, uma vez que não requer quaisquer dependências externas, é minúsculo - única 16K, e carrega automaticamente o arquivo ini na inicialização. Por exemplo.
Configurable config = Configuration.getInstance();
String host = config.getStringValue("host");
int port = config.getIntValue("port");
new Connection(host, port);
É tão simples como isto .....
//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");