2008-10-10 81 views
85

我正在为Java中的遗留应用程序编写一个嵌入式替换。其中一个要求是旧应用程序所使用的ini文件必须按原样读入新的Java应用程序。这个ini文件的格式是普通的窗口风格,带有标题部分和键=值对,使用#作为评论字符。在Java中解析INI文件的最简单方法是什么?

我尝试使用Java中的Properties类,但当然,如果名称在不同标题之间发生冲突,那当然不起作用。

所以问题是,什么是最简单的方法来读取此INI文件并访问密钥?

回答

104

我用过的图书馆是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)); 
+15

链接:http://ini4j.sourceforge.net/ – alastairs 2009-05-20 09:19:04

+1

不起作用,错误说:“ini文件不能解析为类型“ – Caballero 2013-05-03 15:16:01

+0

@Caballero是的,似乎`IniFile`类被取出,尝试`Ini ini = new Ini(新文件(”/ path/to/file“));` – 2013-11-09 22:23:52

2

另一种选择是Apache Commons Config也有一个从INI files加载类。它的确有一些runtime dependencies,但对于INI文件,它只需要Commons集合,lang和日志记录。

我已经使用Commons Config对其项目的属性和XML配置进行了配置。它非常易于使用并支持一些非常强大的功能。

11

或用标准的Java API,你可以使用java.util.Properties

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

这里有一个简单,但功能强大的例子中,使用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-langcommons-logging。根据你在做什么,你可能需要额外的库(参见前面的链接了解详情)。

59

由于mentionedini4j可以用来实现这一点。让我示范另一个例子。

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

[header] 
key = value 

下应该显示value到STDOUT:

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

检查the tutorials更多的例子。

25

就这么简单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)); 
    } 
} 
1

我个人比较喜欢Confucious

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

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

在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; 
} 
相关问题