Java에서 INI 파일을 구문 분석하는 가장 쉬운 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/190629

  •  07-07-2019
  •  | 
  •  

문제

Java에서 레거시 응용 프로그램에 대한 드롭 인 교체품을 작성하고 있습니다. 요구 사항 중 하나는 이전 응용 프로그램을 사용한 INI 파일을 새 Java 응용 프로그램에 읽어야한다는 것입니다. 이 INI 파일의 형식은 댓글을위한 문자로 #을 사용하는 헤더 섹션과 키 = 값 쌍이있는 일반적인 Windows 스타일입니다.

Java의 Properties 클래스를 사용해 보았지만 물론 다른 헤더 사이에 이름 충돌이 있으면 작동하지 않습니다.

따라서 문제는이 INI 파일에서 가장 쉬운 방법이 무엇입니까?

도움이 되었습니까?

해결책

내가 사용한 도서관은 INI4J. 가볍고 INI 파일을 쉽게 구문 분석합니다. 또한 설계 목표 중 하나는 표준 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));

다른 팁

처럼 말하는, INI4J 이를 달성하는 데 사용할 수 있습니다. 다른 예를 보여 드리겠습니다.

다음과 같은 INI 파일이있는 경우 :

[header]
key = value

다음이 표시되어야합니다 value stdout에 :

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

다음은 Apache 클래스를 사용하는 간단하지만 강력한 예입니다. 계층 적 인식:

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 구성에는 여러 가지가 있습니다 런타임 종속성. 최소한, 커먼즈 라인 그리고 커먼즈 로깅 필요합니다. 수행하는 작업에 따라 추가 라이브러리가 필요할 수 있습니다 (자세한 내용은 이전 링크 참조).

또는 표준 Java API를 사용하여 사용할 수 있습니다 java.util.properties:

Properties props = new Properties();
try (FileInputStream in = new FileInputStream(path)) {
    props.load(in);
}

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

또 다른 옵션입니다 Apache Commons 구성 또한로드를위한 클래스도 있습니다 INI 파일. 일부가 있습니다 런타임 종속성, 그러나 INI 파일의 경우 Commons Collections, Lang 및 Logging 만 있으면됩니다.

속성 및 XML 구성으로 프로젝트에 Commons 구성을 사용했습니다. 사용하기가 매우 쉽고 몇 가지 강력한 기능을 지원합니다.

당신은 Jinifile을 시도 할 수 있습니다. 델파이의 Tinifile의 번역이지만 Java의 경우

https://github.com/subzane/jinifile

나는 개인적으로 선호합니다 유교.

외부 종속성이 필요하지 않기 때문에 좋습니다. 작고 16k에 불과하며 초기화시 INI 파일을 자동으로로드합니다. 예를 들어

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

이것만큼 간단합니다 .....

//import java.io.FileInputStream;
//import java.io.FileInputStream;

Properties prop = new Properties();
//c:\\myapp\\config.ini is the location of the ini file
//ini file should look like host=localhost
prop.load(new FileInputStream("c:\\myapp\\config.ini"));
String host = prop.getProperty("host");
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top