2008-10-10 93 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; 
} 
相關問題