J'écris une solution de remplacement pour une application existante 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, en utilisant # comme caractère de commentaire.
J'ai essayé d'utiliser la classe Properties de Java, mais cela ne fonctionnera bien sûr pas s'il y a des conflits de noms entre différents en-têtes.
La question est donc de savoir quel serait le moyen le plus facile de lire dans ce fichier INI et d’accéder aux clés.
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 aucune dépendance ésotérique 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));
Comme mentionné , ini4j peut être utilisé pour y parvenir. Laissez-moi vous montrer un autre exemple.
Si nous avons un fichier INI comme celui-ci:
[header]
key = value
Ce qui suit devrait afficher value
to STDOUT:
Ini ini = new Ini(new File("/path/to/file"));
System.out.println(ini.get("header", "key"));
Vérifiez les tutoriels 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");
}
Configuration commune a un certain nombre de dépendances d'exécution . Au minimum, commons-lang et commons-logging sont 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 aussi une classe pour charger depuis INI fichiers . Il a quelques dépendances d'exécution , mais pour les fichiers INI, il ne devrait nécessiter que des collectes communes, des langages et une 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
Personnellement, je préfère Confucious .
C'est agréable, car il ne nécessite aucune dépendance externe, il est minuscule - seulement 16K, et charge automatiquement votre fichier ini à l'initialisation. Par exemple.
Configurable config = Configuration.getInstance();
String Host = config.getStringValue("Host");
int port = config.getIntValue("port");
new Connection(Host, port);