我正在为Java中的遗留应用程序编写一个嵌入式替换。其中一个要求是旧应用程序所使用的ini文件必须按原样读入新的Java应用程序。这个ini文件的格式是普通的窗口风格,带有标题部分和键=值对,使用#作为评论字符。在Java中解析INI文件的最简单方法是什么?
我尝试使用Java中的Properties类,但当然,如果名称在不同标题之间发生冲突,那当然不起作用。
所以问题是,什么是最简单的方法来读取此INI文件并访问密钥?
我正在为Java中的遗留应用程序编写一个嵌入式替换。其中一个要求是旧应用程序所使用的ini文件必须按原样读入新的Java应用程序。这个ini文件的格式是普通的窗口风格,带有标题部分和键=值对,使用#作为评论字符。在Java中解析INI文件的最简单方法是什么?
我尝试使用Java中的Properties类,但当然,如果名称在不同标题之间发生冲突,那当然不起作用。
所以问题是,什么是最简单的方法来读取此INI文件并访问密钥?
我用过的图书馆是ini4j。它轻量级并轻松解析ini文件。此外,它不使用深奥的依赖10,000其他jar文件,作为设计目标之一是只使用标准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));
另一种选择是Apache Commons Config也有一个从INI files加载类。它的确有一些runtime dependencies,但对于INI文件,它只需要Commons集合,lang和日志记录。
我已经使用Commons Config对其项目的属性和XML配置进行了配置。它非常易于使用并支持一些非常强大的功能。
或用标准的Java API,你可以使用java.util.Properties:
new Properties() props = rowProperties.load(new FileInputStream(path));
这里有一个简单,但功能强大的例子中,使用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");
}
共享配置有许多runtime dependencies。至少需要commons-lang和commons-logging。根据你在做什么,你可能需要额外的库(参见前面的链接了解详情)。
由于mentioned,ini4j可以用来实现这一点。让我示范另一个例子。
如果我们有一个INI文件是这样的:
[header]
key = value
下应该显示value
到STDOUT:
Ini ini = new Ini(new File("/path/to/file"));
System.out.println(ini.get("header", "key"));
检查the tutorials更多的例子。
你可以试试JINIFile。是TIniFile从德尔福的翻译,但对Java
就这么简单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));
}
}
我个人比较喜欢Confucious。
这很好,因为它不需要任何外部依赖,它很小 - 只有16K,并且在初始化时自动加载你的ini文件。例如。
Configurable config = Configuration.getInstance();
String host = config.getStringValue("host");
int port = config.getIntValue("port");
new Connection(host, port);
在19线,延长java.util.Properties
解析成多个部分:
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;
}
链接:http://ini4j.sourceforge.net/ – alastairs 2009-05-20 09:19:04
不起作用,错误说:“ini文件不能解析为类型“ – Caballero 2013-05-03 15:16:01
@Caballero是的,似乎`IniFile`类被取出,尝试`Ini ini = new Ini(新文件(”/ path/to/file“));` – 2013-11-09 22:23:52