在Java中parsingINI文件最简单的方法是什么?

我正在为Java中的遗留应用程序编写一个embedded式替代品。 其中一个要求是旧应用程序所使用的ini文件必须原样读入新的Java应用程序。 这个ini文件的格式是普通的窗口样式,带有标题部分和键=值对,使用#作为注释的字符。

我尝试使用从Java的属性类,但当然不会工作,如果名称冲突不同的标题之间。

所以问题是,在这个INI文件中读取和访问密钥最简单的方法是什么?

我用过的库是ini4j 。 它轻量级,轻松parsingini文件。 另外,它不使用深奥的依赖关系来处理10,000个其他的jar文件,因为其中一个devise目标是只使用标准的Java API

这是一个如何使用图书馆的例子:

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

如前所述 , ini4j可以用来实现这一点。 让我示范另一个例子。

如果我们有这样一个INI文件:

 [header] key = value 

以下应该显示STDOUT的value

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

查看教程以获取更多示例。

像80行一样简单:

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

下面是一个简单但function强大的例子,使用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有许多运行时依赖关系 。 至less需要commons-lang和commons-logging 。 根据你在做什么,你可能需要额外的库(请参阅前面的链接了解详情)。

或者使用标准的Java API,您可以使用java.util.Properties :

 new Properties() props = rowProperties.load(new FileInputStream(path)); 

另一种select是Apache Commons Config也有一个从INI文件加载的类。 它确实有一些运行时依赖 ,但是对于INI文件,它只需要Commons集合,lang和日志logging。

我已经使用它们的属性和XMLconfiguration在项目上使用Commons Config。 这是非常容易使用和支持一些非常强大的function。

你可以试试JINIFile。 是delphiTIniFile的翻译,但是对于Java

https://github.com/SubZane/JIniFile

在19行中,扩展java.util.Properties以parsing为多个部分:

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

我个人比较喜欢孔子 。

这很好,因为它不需要任何外部依赖,它很小 – 只有16K,并在初始化时自动加载你的ini文件。 例如

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