1. 개요

INI 파일은 Windows 또는 MS-DOS용 초기화 또는 구성 파일입니다. 섹션의 키-값 쌍으로 구성된 일반 텍스트 콘텐츠가 있습니다 . Java의 기본 .properties 파일 또는 기타 형식으로 애플리케이션을 구성하는 것을 선호할 수 있지만 때때로 기존 INI 파일의 데이터를 사용해야 할 수도 있습니다.

이 사용방법(예제)에서는 도움이 될 수 있는 몇 가지 라이브러리를 살펴보겠습니다. 또한 INI 파일의 데이터 로 POJO 를 채우는 방법도 살펴보겠습니다 .

2. 샘플 INI 파일 생성

샘플 INI 파일 sample.ini 부터 시작하겠습니다 .

; for 16-bit app support
[fonts]
letter=bold
text-size=28

[background]
color=white

[RequestResult]
RequestCode=1

[ResponseResult]
ResultCode=0

이 파일에는 명명을 위해 소문자, 케밥 케이스 및 대문자 카멜 케이스를 혼합하여 사용하는 네 개의 섹션이 있습니다. 문자열 또는 숫자 값이 있습니다.

3. ini4j 를 사용하여 INI 파일 구문 분석

ini4j 는 INI 파일에서 구성을 읽기 위한 경량 라이브러리입니다. 2015년 이후로 업데이트가 되지 않았습니다.

3.1. ini4j 설치

ini4j 라이브러리 를 사용하려면 먼저 pom.xml 에 의존성 을 추가해야 합니다 .

<dependency>
    <groupId>org.ini4j</groupId>
    <artifactId>ini4j</artifactId>
    <version>0.5.4</version>
</dependency>

3.2. ini4j 에서 INI 파일 열기

Ini 객체 를 구성하여  ini4j  에서 INI 파일을 열 수 있습니다 .

File fileToParse = new File("sample.ini");
Ini ini = new Ini(fileToParse);

이제 이 개체에는 섹션과 키가 포함됩니다.

3.3. 섹션 키 읽기

Ini 클래스 의 get() 함수를  사용하여 INI 파일의 섹션에서 키를 읽을 수 있습니다 .

assertThat(ini.get("fonts", "letter"))
  .isEqualTo("bold");

3.4. Map로 변환

전체 INI 파일을 INI 파일 의 계층 구조를 나타내는 Java 기본 데이터 구조인 Map<String, Map<String, String>> 으로 변환하는 것이 얼마나 쉬운지 살펴보겠습니다  .

public static Map<String, Map<String, String>> parseIniFile(File fileToParse)
  throws IOException {
    Ini ini = new Ini(fileToParse);
    return ini.entrySet().stream()
      .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
}

여기서  Ini 객체의 entrySet 은  기본적으로 String 과  Map<String, String> 의 키-값 쌍입니다  . Ini 의 내부 표현  은 거의  Map 이므로  stream() 및  toMap() 수집기 를 사용하여  일반 Map 으로 쉽게 변환할 수 있습니다.

이제 get() 을 사용하여 이 맵에서 섹션을 읽을 수 있습니다 .

assertThat(result.get("fonts").get("letter"))
  .isEqualTo("bold");

Ini 클래스 는  즉시 사용하기가 매우 쉽고  Map 으로 변환하는 것이 필요하지 않을 수도 있지만 나중에 사용 방법을 찾게 될 것입니다.

그러나  ini4j 는 오래된 라이브러리이며 잘 관리되지 않는 것 같습니다. 다른 옵션을 고려해 봅시다.

4. Apache Commons를 사용하여 INI 파일 구문 분석

Apache Commons에는 INI 파일을 처리하기 위한 보다 정교한 도구가 있습니다. 이것은 읽기 및 쓰기를 위해 전체 파일을 모델링할 수 있지만 구문 분석 기능에만 중점을 둘 것입니다.

4.1. Commons 구성 설치

pom.xml 에 필요한 의존성 을 추가하여 시작하겠습니다 .

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-configuration2</artifactId>
    <version>2.8.0</version>
</dependency>

버전 2.8.0은 2022년에 업데이트되었으며 ini4j 보다 최신 버전 입니다.

4.2. INI 파일 열기

INIConfiguration 객체를 선언하고  Reader 에 전달 하여 INI 파일을 열 수 있습니다  .

INIConfiguration iniConfiguration = new INIConfiguration();
try (FileReader fileReader = new FileReader(fileToParse)) {
    iniConfiguration.read(fileReader);
}

여기에서 우리는 FileReader  를 열기 위해 try-with-resources 패턴을  사용한 다음 INIConfiguration 개체에  read 함수로 그것을 읽도록 요청했습니다.

4.3. 섹션 키 읽기

INIConfiguration  클래스에는  섹션을 읽는 getSection() 함수와 키를 읽는 반환된 객체의  getProperty ( ) 함수가 있습니다 .

String value = iniConfiguration.getSection("fonts")
  .getProperty("letter")
  .toString();
assertThat(value)
  .isEqualTo("bold");

getProperty() 는 String 이 아닌  Object 를  반환  하므로 String 으로 변환해야 합니다  .

4.4. Map로 변환

이전과 같이 INIConfiguration 을  Map 으로 변환할 수도 있습니다  . 이것은 ini4j 보다 약간 더 복잡합니다  .

Map<String, Map<String, String>> iniFileContents = new HashMap<>();

for (String section : iniConfiguration.getSections()) {
    Map<String, String> subSectionMap = new HashMap<>();
    SubnodeConfiguration confSection = iniConfiguration.getSection(section);
    Iterator<String> keyIterator = confSection.getKeys();
    while (keyIterator.hasNext()) {
        String key = keyIterator.next();
        String value = confSection.getProperty(key).toString();
        subSectionMap.put(key, value);
    }
    iniFileContents.put(section, subSectionMap);
}

모든 섹션을 가져오려면 이름을 찾기 위해 getSections() 를 사용해야  합니다. 그런 다음  getSection() 은 각 섹션을 제공할 수 있습니다.

그런 다음 섹션에 대한 모든 키를 제공 하는 Iterator 를 사용하고 각각에 getProperty() 를 사용하여 키-값 쌍을 가져올 수 있습니다.

여기 에서 을 생성하기는 더 어렵지만 더 평범한 데이터 구조의 장점은 시스템의 다른 부분에서 구문 분석하는 INI 파일을 숨길 수 있다는 것입니다. 또는 구성을 POJO로 변환할 수 있습니다.

5. INI 파일을 POJO로 변환

Jackson 을 사용 하여 Map 구조를 POJO로 변환 할 수 있습니다. Jackson이 원본 INI 파일의 다양한 명명 규칙을 이해하는 데 도움이 되도록 역직렬화 어노테이션으로 POJO를 장식할 수 있습니다. POJO는 지금까지 본 어떤 데이터 구조보다 사용하기 쉽습니다.

5.1. 잭슨 가져오기

pom.xml 에 Jackson 을  추가해야 합니다 .

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.13.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.13.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>

5.2. 일부 POJO 정의

샘플 파일 의  글꼴 섹션은 해당 속성에 kebab-case를 사용합니다. 해당 섹션을 나타내는 클래스를 정의해 보겠습니다.

@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
public static class Fonts {
    private String letter;
    private int textSize;

    // getters and setters
}

여기에서는 JsonNaming 어노테이션을 사용하여 속성에 사용된 사례를 설명했습니다.

마찬가지로 RequestResult 섹션에는 대문자 카멜 케이스를 사용하는 속성이 있습니다.

@JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class)
public static class RequestResult {
    private int requestCode;

    // getters and setters
}

섹션 이름 자체는 다양한 케이스이므로 JsonProperty 어노테이션을 사용하여 기본 소문자 카멜 케이스 이름 지정과의 편차를 표시하여 부모 개체의 각 섹션을 선언할 수 있습니다.

public class MyConfiguration {
    private Fonts fonts;
    private Background background;

    @JsonProperty("RequestResult")
    private RequestResult requestResult;

    @JsonProperty("ResponseResult")
    private ResponseResult responseResult;

    // getters and setters
}

5.3. Map에서 POJO로 변환

이제 라이브러리 중 하나를 사용하여 INI 파일을  Map 으로 읽을  수 있고 파일 내용을 POJO로 모델링할 수 있으며 Jackson ObjectMapper 를 사용하여 변환을 수행할 수 있습니다.

ObjectMapper objectMapper = new ObjectMapper();
Map<String, Map<String, String>> iniKeys = parseIniFile(TEST_FILE);
MyConfiguration config = objectMapper.convertValue(iniKeys, MyConfiguration.class);

전체 파일이 올바르게 로드되었는지 확인해 보겠습니다.

assertThat(config.getFonts().getLetter()).isEqualTo("bold");
assertThat(config.getFonts().getTextSize()).isEqualTo(28);
assertThat(config.getBackground().getColor()).isEqualTo("white");
assertThat(config.getRequestResult().getRequestCode()).isEqualTo(1);
assertThat(config.getResponseResult().getResultCode()).isZero();

textSizerequestCode 와 같은 숫자 속성 이 POJO에 숫자로 로드되었다는 점에 유의해야 합니다.

6. 라이브러리와 접근법의 비교

ini4j 라이브러리는 사용 이  매우 간단하며 본질적으로 간단한 과 유사한 구조입니다. 그러나 이것은 정기적인 업데이트가 없는 오래된 라이브러리입니다.

Apache Commons 솔루션은 기능이 더 풍부하고 정기적인 업데이트가 있지만 사용하려면 조금 더 많은 작업이 필요합니다.

7. 결론

이 기사에서는 몇 가지 오픈 소스 라이브러리를 사용하여 INI 파일을 읽는 방법을 살펴보았습니다. 개별 키를 읽는 방법과 전체 파일을 반복하여 Map 을 생성하는 방법을 살펴보았습니다 .

그런 다음 Jackson을 사용하여 Map 에서 POJO 로 변환하는 방법을 살펴보았습니다  .

항상 그렇듯이 예제 코드는 GitHub 에서 사용할 수 있습니다 .

Jackson footer banner