108

Java でレガシー アプリケーションのドロップイン置換を作成しています。要件の 1 つは、古いアプリケーションが使用していた ini ファイルをそのまま新しい Java アプリケーションに読み込む必要があることです。この ini ファイルの形式は、一般的な Windows スタイルで、ヘッダー セクションと key=value のペアがあり、コメントの文字として # が使用されます。

Java の Properties クラスを使用してみましたが、もちろん、異なるヘッダー間で名前が衝突すると機能しません。

問題は、この INI ファイルを読み取ってキーにアクセスする最も簡単な方法は何でしょうか?

4

13 に答える 13

129

私が使用したライブラリはini4jです。軽量で、ini ファイルを簡単に解析できます。また、設計目標の 1 つは標準の Java API のみを使用することであったため、10,000 の他の jar ファイルへの難解な依存関係を使用しません。

これは、ライブラリの使用方法の例です。

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));
于 2008-10-10T09:22:12.433 に答える
66

前述のように、ini4jを使用してこれを実現できます。もう 1 つ例を示しましょう。

次のような INI ファイルがあるとします。

[header]
key = value

value以下がSTDOUT に表示されます。

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

その他の例については、チュートリアルを確認してください。

于 2011-01-31T14:17:02.020 に答える
31

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 ));
   }
}
于 2013-03-26T13:34:21.747 に答える
17

以下は、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 には、多くの実行時依存関係があります。少なくとも、commons-langcommons-loggingが必要です。何をしているかによっては、追加のライブラリが必要になる場合があります (詳細については、前のリンクを参照してください)。

于 2009-01-28T07:57:43.150 に答える
15

または、標準の Java API を使用すると、java.util.Propertiesを使用できます。

Properties props = new Properties();
try (FileInputStream in = new FileInputStream(path)) {
    props.load(in);
}
于 2008-10-13T08:41:40.253 に答える
11

18 行で、 を拡張し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("]"))
                return result.put(header.substring(1, header.length() - 1), 
                        section = new Properties());
            else
                return section.put(key, value);
        }

    }.load(reader);
    return result;
}
于 2016-12-11T08:59:52.607 に答える
2

JINIFileを試すことができます。DelphiからのTIniFileの翻訳ですが、Java用です

https://github.com/SubZane/JIniFile

于 2013-01-08T10:35:02.010 に答える
2

別のオプションとして、Apache Commons ConfigにはINI ファイルからロードするためのクラスもあります。いくつかのランタイム依存関係がありますが、INI ファイルの場合は、Commons コレクション、lang、およびログのみが必要です。

プロパティと XML 構成を含むプロジェクトで Commons Config を使用しました。非常に使いやすく、かなり強力な機能をサポートしています。

于 2008-10-10T23:05:09.140 に答える