fconfigure — 채널의 옵션 설정·조회하기

fconfigure — 채널의 옵션 설정·조회하기

파일이나 소켓을 다룰 때 인코딩, 버퍼링, 개행 변환, 차단 여부 같은 동작을 정하고 싶을 때가 많아요. 예를 들어 일본어 파일을 읽거나 이진 데이터를 주고받거나, 소켓을 비차단으로 만들 때요. 이 모든 채널 옵션을 다루는 명령이 fconfigure예요.

출처: Tcl 공식 문서 — fconfigure

본문

시그니처

fconfigure channelId
fconfigure channelId name
fconfigure channelId name value ?name value ...?

설명

fconfigure 명령은 채널의 옵션을 설정하고 가져와요.

ChannelId는 옵션을 설정·조회할 채널을 가리키고, 표준 채널(stdin, stdout, stderr), open·socket 호출의 반환값, 또는 Tcl 확장이 제공한 채널 생성 명령의 결과 같은 열려 있는 채널을 가리켜야 해요.

name·value 인자를 주지 않으면 명령은 채널에 대한 옵션 이름과 값이 번갈아 나오는 목록을 반환해요. name만 주고 value를 주지 않으면 주어진 옵션의 현재 값을 반환해요. name·value 쌍을 하나 이상 주면 각 옵션을 해당 값으로 설정하고, 이 경우 반환값은 빈 문자열이에요.

아래 설명하는 옵션은 모든 채널에서 지원돼요. 게다가 각 채널 타입은 자신만 지원하는 옵션을 추가할 수 있어요. 각 타입의 채널을 만드는 명령의 매뉴얼 항목에서 해당 채널 타입이 지원하는 옵션을 보세요. 예를 들어 소켓의 추가 옵션은 socket 명령, 직렬 장치의 추가 옵션은 open 명령 매뉴얼 항목을 참고하세요.

-blocking boolean

-blocking 옵션은 채널의 I/O 연산이 프로세스를 무기한 차단할 수 있는지 결정해요. 옵션 값은 적절한 불리언 값이어야 해요. 채널은 보통 차단 모드에 있어요. 채널을 비차단 모드로 두면 gets, read, puts, flush, close 명령의 동작에 영향을 줘 비동기로 동작하게 해요. 자세한 건 그 명령들의 문서를 보세요. 비차단 모드가 올바르게 동작하려면 응용 프로그램이 Tcl 이벤트 루프를 사용해야 해요(예: Tcl_DoOneEvent를 호출하거나 vwait 명령을 호출).

-buffering newValue

newValuefull이면 I/O 시스템은 내부 버퍼가 가득 차거나 flush 명령이 호출될 때까지 출력을 버퍼링해요. newValueline이면 I/O 시스템은 개행 문자가 출력될 때마다 채널의 출력을 자동으로 플러시해요. newValuenone이면 I/O 시스템은 모든 출력 연산 후에 자동으로 플러시해요. 기본적으로 -buffering은 터미널-류 장치에 연결된 채널을 제외하고 full로 설정되며, 그런 채널의 초기 설정은 line이에요. 게다가 stdin·stdout은 처음에 line으로, stderrnone으로 설정돼요.

-buffersize newSize

newValue는 정수여야 해요. 그 값은 이 채널의 입력·출력을 저장하기 위해 이후 할당될 버퍼의 크기(바이트)를 설정하는 데 쓰여요. newValue는 1과 1,000,000 사이여야 해서, 1에서 백만 바이트 크기의 버퍼를 허용해요.

-encoding name

이 옵션은 채널의 인코딩을 지정해서 Tcl에서 쓰기 위해 데이터를 Unicode로(또는 Unicode에서) 변환할 수 있게 해 줘요. 예를 들어 Tcl이 shiftjis 일본어 파일에서 문자를 읽어 제대로 처리·표시하려면 인코딩을 shiftjis로 설정해요. 그러면 이후 채널에서 읽을 때 일본어 파일의 바이트가 읽히면서 Unicode로 변환돼요. 쓰기도 지원돼요 — Tcl 문자열이 채널에 쓰이면 출력에서 지정 인코딩으로 자동 변환돼요.

파일이 순수 이진 데이터(예: JPEG 이미지)를 담고 있으면 채널의 인코딩을 binary로 구성해야 해요. 그러면 Tcl은 파일의 데이터에 아무 해석도 할당하지 않고 원시 바이트를 읽거나 써요. 이 바이트 중심 데이터를 조작하려면 Tcl binary 명령을 쓸 수 있어요. 이진 데이터를 전송하려면 보통 -translation 옵션을 binary로 설정하는 게 더 좋아요. 스트림의 바이트에 대한 다른 자동 해석도 꺼지기 때문이에요.

새로 연 채널의 기본 인코딩은 운영체제 인터페이스에 쓰이는 것과 같은 플랫폼·로케일 의존 시스템 인코딩으로, encoding system이 반환하는 것이에요.

-eofchar char

-eofchar {inChar outChar}

이 옵션은 파일 끝 마커로 Control-z(\x1A)를 쓰는 DOS 파일시스템을 지원해요. char가 빈 문자열이 아니면 이 문자는 입력 중 만나면 파일 끝을 알리는 신호가 돼요. 출력에 대해서는 파일 끝 문자가 채널이 닫힐 때 출력돼요. char가 빈 문자열이면 특별한 파일 끝 문자 마커가 없어요. 읽기-쓰기 채널에서는 두 요소짜리 목록이 각각 입력·출력에 대한 파일 끝 마커를 지정해요. 편의상 읽기-쓰기 채널의 파일 끝 문자를 설정할 때 읽기·쓰기 둘 다에 적용되는 단일 값을 지정할 수 있어요. 읽기-쓰기 채널의 파일 끝 문자를 조회하면 항상 두 요소짜리 목록이 반환돼요. -eofchar의 기본값은 Windows 아래의 파일을 제외한 모든 경우에 빈 문자열이에요. 그 경우 -eofchar는 읽기에 Control-z(\x1A), 쓰기에 빈 문자열이에요. -eofchar 값의 허용 범위는 \x01 - \x7F이에요. 이 범위 밖의 값으로 설정하면 에러가 나요.

-translation mode

-translation {inMode outMode}

Tcl 스크립트에서 줄의 끝은 항상 단일 개행 문자(\n)로 표현돼요. 하지만 실제 파일·장치에서 줄의 끝은 플랫폼마다, 또는 같은 플랫폼의 장치마다 다르게 표현될 수 있어요. 예를 들어 UNIX에서는 파일에 개행을 쓰는 반면, 네트워크 연결에서는 보통 캐리지-리턴-라인피드 시퀀스를 써요. 입력(즉 gets·read)에서 Tcl I/O 시스템은 외부 줄 끝 표현을 개행 문자로 자동 변환해요. 출력(즉 puts)에서 I/O 시스템은 개행을 외부 줄 끝 표현으로 변환해요. 기본 변환 모드 auto는 모든 일반적인 경우를 자동으로 처리하지만, -translation 옵션은 줄 끝 변환에 대한 명시적 제어를 제공해요.

-translation과 연관된 값은 읽기 전용·쓰기 전용 채널에 대해 단일 항목이에요. 읽기-쓰기 채널에서는 두 요소짜리 목록이며, 읽기 변환 모드가 목록의 첫 요소, 쓰기 변환 모드가 둘째 요소예요. 편의상 읽기-쓰기 채널의 변환 모드를 설정할 때 읽기·쓰기 둘 다에 적용되는 단일 값을 지정할 수 있어요. 읽기-쓰기 채널의 변환 모드를 조회하면 항상 두 요소짜리 목록이 반환돼요. 현재 지원되는 값은 다음과 같아요.

auto

입력 변환 모드로 auto는 개행(lf), 캐리지 리턴(cr), 캐리지 리턴 뒤 개행(crlf) 중 어떤 것이든 줄 끝 표현으로 취급해요. 줄 끝 표현은 줄마다 바뀔 수도 있고, 모든 경우가 개행으로 변환돼요. 출력 변환 모드로 auto는 플랫폼 특정 표현을 선택해요. 모든 플랫폼의 소켓에 대해 Tcl은 crlf를, 모든 Unix 계열에 대해 lf를, 다양한 Windows 계열에 대해 crlf를 선택해요. -translation의 기본 설정은 입력·출력 모두 auto예요.

binary

줄 끝 변환이 수행되지 않아요. 이것은 lf 모드와 거의 동일하지만, 추가로 binary 모드는 파일 끝 문자를 빈 문자열로 설정하고(비활성화), 인코딩을 binary로 설정해요(인코딩 필터 비활성화). 자세한 내용은 -eofchar·-encoding 설명을 보세요.

내부적으로, 즉 변환기의 실제 동작에 관해서는 이 값은 lf와 동일해서 조회 시 그렇게 보고돼요. binary로 변환을 설정했더라도요.

cr

기본 파일·장치의 줄 끝이 단일 캐리지 리턴 문자로 표현돼요. 입력 변환 모드로 cr 모드는 캐리지 리턴을 개행 문자로 변환해요. 출력 변환 모드로 cr 모드는 개행 문자를 캐리지 리턴으로 변환해요.

crlf

기본 파일·장치의 줄 끝이 캐리지 리턴 문자 뒤에 라인피드 문자가 이어지는 것으로 표현돼요. 입력 변환 모드로 crlf 모드는 캐리지-리턴-라인피드 시퀀스를 개행 문자로 변환해요. 출력 변환 모드로 crlf 모드는 개행 문자를 캐리지-리턴-라인피드 시퀀스로 변환해요. 이 모드는 보통 Windows 플랫폼과 네트워크 연결에서 쓰여요.

lf

기본 파일·장치의 줄 끝이 단일 개행(라인피드) 문자로 표현돼요. 이 모드에서는 입력·출력 중 어떤 변환도 일어나지 않아요. 이 모드는 보통 UNIX 플랫폼에서 쓰여요.

표준 채널

Tcl 표준 채널(stdin, stdout, stderr)은 Tcl 라이브러리가 연 다른 모든 채널처럼 이 명령으로 구성할 수 있어요. 위 표준 옵션 외에도 현재 타입에 따른 특별 옵션을 지원해요. 예를 들어 Unix 시스템에서 흔한 inet 슈퍼-서버가 Tcl 응용 프로그램을 시작하면 그 Tcl 표준 채널은 소켓이 되어 소켓 옵션을 지원해요.

예제

터미널이든 아니든 stdout에 출력을 즉시 보내도록 Tcl에 지시해요:

fconfigure stdout -buffering none

소켓을 열고 다른 이벤트 처리를 절대 차단하지 않고 소켓에서 줄을 읽어요:

set s [socket some.where.com 12345]
fconfigure $s -blocking 0
fileevent $s readable "readMe $s"
proc readMe chan {
 if {[gets $chan line] < 0} {
 if {[eof $chan]} {
 close $chan
 return
 }
 # Could not read a complete line this time; Tcl's
 # internal buffering will hold the partial line for us
 # until some more data is available over the socket.
 } else {
 puts stdout $line
 }
}

파일에서 PPM 형식 이미지를 읽어요:

# Open the file and put it into Unix ASCII mode
set f [open teapot.ppm]
fconfigure $f -encoding ascii -translation lf

# Get the header
if {[gets $f] ne "P6"} {
 error "not a raw-bits PPM"
}

# Read lines until we have got non-comment lines
# that supply us with three decimal values.
set words {}
while {[llength $words] < 3} {
 gets $f line
 if {[string match "#*" $line]} continue
 lappend words {*}[join [scan $line %d%d%d]]
}

# Those words supply the size of the image and its
# overall depth per channel. Assign to variables.
lassign $words xSize ySize depth

# Now switch to binary mode to pull in the data,
# one byte per channel (red,green,blue) per pixel.
fconfigure $f -translation binary
set numDataBytes [expr {3 * $xSize * $ySize}]
set data [read $f $numDataBytes]

close $f

더 알아보기

  • close, flush, gets, open, puts, read, socket, Tcl_StandardChannels
  • 키워드: blocking, buffering, carriage return, end of line, flushing, linemode, newline, nonblocking, platform, translation, encoding, filter, byte array, binary