본문으로 바로가기

INI 파일 조작 tclini

category 카테고리 없음 2024. 6. 17. 15:52

INI 포맷은 마이크로소프트사의 초창기 MS-Windows부터 제작되어, 간단하면서도 현재까지도 널리 사용되고 있는 포맷입니다. 기존의 Tcl 패키지중 INI 파서는 여러 가지가 존재했지만, Tcl의 제약 사항인 속도 문제에 있어 대량의 데이터를 취급 시에는 느린 속도의 불이익을 감수해야만 했습니다. 이런 속도를 극복한 C용 INI 파서 라이브러리를 Tcl로 바인딩한 패키지를 찾고자 여러 시도를 해보 았지만 찾을 수가 없었습니다. 때문에 본인은 C언어의 INI 파서 라이브러인 libini (http://libini.sourceforge.net)를 Tcl로 바인딩하였으며, 패키지 이름은 tclini라 하였습니다. 이번 강좌는 tclini의 사용방법에 대해서 알아봅니다. 현재는 Windows용만 준비되어 있으며, 포럼의 [Tcl/Tk 확장 패키지] 내에서 받으실 수 있습니다.

패키지 로드

tclini는 tclini.dll 단일 파일로만 이루어진 심플한 INI 파서 패키지입니다. 패키지의 로드는 다음과 같이 단순하게 이루어집니다.

load tclini.dll

INI 읽기

tclini에서는 INI 포맷 구성을 다음과 같은 용어로 사용합니다.

[Header]
Key = String

당연한 얘기겠지만, 같은 헤더는 존재할 수 없으며, 같은 헤더 내에서의 같은 키는 존재할수 없습니다. 다음은 테스트로 사용된 INI 파일의 내용입니다.

[header1]
key1=value1
key2=value2

[header2]
key1=value1
key2=value2

아래의 소스는 위의 INI 파일 내에서 원하는 정보를 얻는 예제입니다.

set ini [ini_open "test.ini" r {}]

ini_locateHeading $ini "header1"

set buffer [ini_createBuffer 1000]

ini_locateKey $ini "key1"
if { [ini_readString $ini $buffer] != -1 } {
	puts "key1 = [ini_getBuffer $buffer]"
}

ini_locateKey $ini "key2"
if { [ini_readString $ini $buffer] != -1 } {
	puts "key2 = [ini_getBuffer $buffer]"
}
ini_deleteBuffer $buffer
ini_close $ini

 

결과는 다음과 같습니다.

key1 = value1
key2 = value2

 

ini_open 커맨드는, 읽기 모드와 쓰기 모드로 파일을 열어 파일 포인터를 돌려주며, 세 번째 인자는 코멘트 처리를 하는 데 사용되며, 통상 공백으로 지정합니다. ini_locateHeading 커맨드는 헤더의 위치를 지정하는 데 사용합니다. ini_locateKey 커맨드는 위에서 지정한 헤더 내의 키를 지정합니다. ini_readString 커맨드는 지정한 키의 값을 읽어 들입니다. 이때 ini_readString 커맨드는 리턴값으로 키의 값을 리턴하는 방식이 아닌, ini_createBuffer로 생성한 버퍼로 읽어 들인 값을 저장합니다. 통상적으로 버퍼의 생성은 최대 문자열 길이로 한번만 생성하여 사용하면 됩니다. 이때 키를 정상적으로 읽어들였다면, ini_readString 커맨드는 읽어들인 값의 문자열 길이를, 실패 시에는 -1을 리턴합니다. 버퍼 내에 저장된 키의 값은 ini_getBuffer 커맨드로 읽어 들이며, 사용 후에는 반드시 ini_deleteBuffer 커맨드로 버퍼를 삭제합니다. ini_close 커맨드는 INI 파일의 액세스를 종료합니다.

INI 쓰기

쓰기는 읽기와 마찬가지로 간단한 형식으로 이루어지기 때문에 예제만 제시합니다.

set ini [ini_open "test.ini" r {}]

ini_locateHeading $ini "header1"

set buffer [ini_createBuffer 1000]

ini_locateKey $ini "key1"
if { [ini_readString $ini $buffer] != -1 } {
	puts "key1 = [ini_getBuffer $buffer]"
}

ini_locateKey $ini "key2"
if { [ini_readString $ini $buffer] != -1 } {
	puts "key2 = [ini_getBuffer $buffer]"
}
ini_deleteBuffer $buffer
ini_close $ini

마치며

복잡한 구조를 취급 시는 INI 포맷보단 XML 포맷을 이용하는 것이 바람직하며, 단순한 구조를 취급시는 INI포맷이 유리할 것입니다. 또한 기존의 순수 Tcl로 만들어진 INI 파서 패키지보다 속도면에서 월등히 뛰어나기 때문에 tclini는 유용하게 사용될 수 있을 것입니다.