Tcl의 파일

admin의 아바타

Tcl은 플랫폼에 독립적인 파일 조작 방법을 제공하고 있습니다. 일반적으로, UNIX, Windows, Macintosh는 각각 다른 파일명 규칙을 갖고 있습니다. 예를 들면, UNIX의 파일명의 구분자(separator)는 슬래쉬(/), Windows는 백 슬래쉬(\), Macintosh는 콜론(:)입니다. Tcl은 네이티브 형식과 UNIX형식의 네이밍(naming) 컨벤션(convention)을 허용함으로써, 플랫폼에 독립적인 파일 패스를 지원하고 있습니다. 즉, 어느 플랫폼에서도 UNIX스타일의 슬래쉬 세퍼레이터 형식의 패스를 사용할수 있습니다.

# Windows 네이티브 형식 
C:\Program Files\Application\Foo

# Windows UNC 형식 
\\Host\Share\Foo

# UNIX 형식 
C:/Program Files/Application/Foo

실제로는, Windows와 Macintosh는 드라이브이름 개념이 있기 때문에 고려가 필요합니다.

file 커맨드

file 커맨드는, 파일의 상태를 체크하는 방법을 제공합니다. 아래는 2개의 파일의 타임 스탬프(time stamp)를 비교한 예입니다.

proc filechk {file1 file2} {
   set time1 [file mtime $file1]
   set time2 [file mtime $file2]
   if {$time1 > $time2} {
      return "$file1 이 최근것입니다."
   } elseif {$time1 < $time2} {
      return "$file2 가 최근것입니다."
   } else {
      return "양쪽이 같습니다."
   }
}
 
filechk /bin/sh /bin/bashfile

커맨드에는 아래와 같은 옵션이 있습니다.

커맨드 설명
file atime name ? time? 파일의 최종 액세스 시간을 10진수로 돌려 준다.time를 지정한다면 액세스 시간을 설정할 수 있다. Windows FAT 파일시스템도 지원한다.
file attributes name, file attributes name ? option?, file attributes name ? option value option value...? 플랫폼에 의존한 파일의 속성을 플래그로 돌려 준다.option과 value를 지정하면, 파일속성을 설정할 수 있다. UNIX 플랫폼에는,-group, -owner, -permissions 옵션이 있다. Windows 플랫폼에는 ,-archive, -hideen, -readonly, -shortname 옵션이 있다. Macintosh 플랫폼에는 ,-creator, -hidden, -readonly, -type 옵션이 있다.
file channels ? pattern? 오픈된 파일의 채널 이름을 리스트 형식으로 돌려 준다.pattern을 지정한다면 패턴에 매치된 이름만을 돌려 준다.
file copy ? -force? ? - -? source target, file copy ? -force? ? - -? source ? soruce...? targetDir 파일 또는 디렉토리를 카피한다.-force 옵션은 에러를 무시하고 강제적으로 카피한다.
file delete ? -force? ? - -? pathname ? pathname? 파일또는 디렉토리를 삭제한다.-force 옵션은, 파일또는 디렉토리가 존재하지 않아도 무시한다.
file dirname name 파일의 패스를 돌려준다.
file executable name 파일이 현재 유저에 의하여 실행 가능하면 1을 돌려 준다.그렇지 않으면 0을 돌려 준다.
file exists name 파일이 존재하면 1을 돌려 준다.그렇지 않으면 0을 돌려 준다.
file extension name 파일의 확장자를 돌려 준다.
file isdirectory name 패스 이름이 디렉토리라면 1을 돌려 준다. 그렇지 않으면 0을 돌려 준다.
file isfile name 패스이름이 파일이면 1을 돌려 준다. 그렇지 않으면 0을 돌려 준다.
file join name ? name...? 1개 이상의 파일명을 결합한 패스 이름을 돌려 준다.
file lstat name varName 파일의 상황을 변수에 돌려 준다.varName는 배열 변수로서 취급한다. 심볼릭 링크를 지원하는 플랫폼에서는 ,아래와 같은 file stat와 동일한 결과가 된다.
file mkdir dir ? dir...? 디렉토리를 작성한다.
file mtime name ? time? 파일의 최종 갱신 시간을 10진수로 돌려 준다.time를 지정한다면 갱신 시간을 설정할 수 있다.
file nativename name 패스이름을 네이티브 형식의 패스이름으로 변환하여 돌려준다.
file owned name 파일이 현재유저의 소유라면 1을 돌려 준다. 그렇지 않으면 0을 돌려 준다.
file pathtype name absolute, relative, volumerelative의 어느 한쪽을 돌려 준다.absolute는 절대 패스, relative는 상대 패스, volumerelative는 드라이브의 상대를 의미한다.
file readable name 파일이 현재 유저에 의하여 읽고 가능하면 1을 돌려 준다. 그렇지 않으면 0을 돌려 준다.
file readlink name 파일이 심볼릭 링크의 경우,실제 파일명을 돌려 준다.
file rename ? -force? ? - -? source target, file rename ? -force? ? - -? source ? soruce...? targetDir 파일 또는 디렉토리의 이름을 변경한다.-force 옵션은 에러를 무시하고 강제적으로 변경한다.
file rootname name 파일의 확장자와 도트(.)를 제외한 패스를 돌려 준다.
file size name 파일의 바이트 사이즈를 돌려 준다.
file split name 패스 이름의 요소를 분할하여 돌려준다.
file tail name 마지막의 디렉토리 구분자(separator) 후의 문자열을 돌려 준다.
file type name 파일의 타입을 돌려 준다.file, directory, characterSpecial, blockSpecial, fifo, link, socket 중 하나
file volume 드라이브의 목록을 돌려준다.
file writable name 파일이 현재 유저에 의하여 쓰기 가능하면 1을 돌려 준다. 그렇지 않으면 0을 돌려 준다.

입/출력 커맨드

아래는 파일의 입/출력에 관계된 커맨드들입니다. open부터 close까지는, 파일 입/출력의 기본 커맨드입니다.

커맨드 설명
open name ? access ? ?permission ? 파일 또는 파이프를 오픈하고, 채널 ID를 리턴한다.
puts ?-nonewline? ? channel? 문자열을 기록한다.
gets channel ? varname? 한 라인을 읽는다.
read channel ? numBytes? 바이트로 구분하여 전 데이타를 읽는다.
read -nonewline channel ? numBytes? 전 데이타를 읽고, 마지막의 \n 은 버린다.
tell channel 현재의 seek offset을 리턴한다.
seek channel offset ? origin? offset만큼 seek하여 지나친다. origin은 start, current, end중의 방향이다.
eof channel 파일이 끝났는지(EOF) 체크한다.
flush channel 기록 버퍼를 플래쉬(flash)한다.
close channel 파일을 닫는다.
fconfigure channel, fconfigure channel name, fconfigure channel name value ? name value...? 채널 옵션의 설정과 참조를 한다.
fblock channel 블록으로 읽어 테스트한다.
fileevent channel readable ? script?, fileevent channel writable ? script? 채널이 읽기 또는 쓰기 가능할 때에 스크립트를 실행한다.
fcopy inchan outchan ?-size size? ?-command script? 채널 사이로 데이타를 복사한다.

아래는 파일을 읽어 표시하는 예제입니다.

if [catch {open "./foo.txt" r} fd] {
   error "파일을 오픈할 수 없습니다"
}
while {[gets $fd line] >= 0} {
   puts stdout $line
}
 
close $fd

아래는 커맨드의 출력을 파이프를 사용하여 읽어 표시하는 예제입니다.

if [catch {open "|/bin/ls -l" r} fd] {
   error "파이프를 오픈할 수 없습니다"
}
while {[gets $fd line] >= 0} {
   puts stdout $line
}
 
close $fd

파일, 파이프, 소켓의 입/출력을 비동기에 처리 할수 있습니다. 비동기에 처리 한다는것은, 동시에 다른 처리를 할수 있다는 말이 됩니다. 다음 예는, 파이프 입력중에 Stop 버튼 또는 ESC키가 눌리면 처리를 중지합니다.

button .start -text Start -command start
button .stop -text Stop -command stop
text .text
grid .start .stop -sticky we
grid .text - -sticky wens
 
proc start {} {
   global fd
   if [catch {open "|ls -lR /" r} fd] {
      error "파이프를 오픈할 수 없습니다."
   }
   .text delete 1.0 end
   fileevent $fd readable async
}
 
proc stop {} {
   global fd
   catch {close $fd}
   .text insert end ***Stoped***\n
   .text see end
}
 
proc async {} {
   global fd
   if [eof $fd] {
      close $fd
   } else {
      gets $fd line
      .text insert end $line\n
      update
      .text see end
   }
}
 
bind . <Escape> stop

참고로 파일 입/출력시에 개행 코드와 인코딩/디코딩 코드도 지정할수 있습니다.