bonkora 님이 제공해 주신 글입니다.
텍스트파일을 읽고 쓰는 작업에 대해 알아보기로 합니다. 사전 프로그램을 예로 들면, 자료의 크기가 작을 경우 자료전체를 메모리로 읽어 들여서 사용자가 필요로 하는 자료를 보여주는 게 효율적일 것입니다. 이런 것이 순차적 접근(sequential access)으로 읽는 방법이라 할 수 있겠죠. 만약 자료가 크다면 한꺼번에 메모리로 읽어 들이는 방법보다는 파일 내에서 자료들이 있는 위치와 크기만을 기억하고 있다가 필요시 그 자료 부분만을 읽어서 사용자에게 보여주는 방법이 더 나을 것입니다. 이것이 임의적 접근(random access)이 되겠습니다.
순차적 접근
먼저 텍스트파일을 읽어서 콘솔 상에서 출력시키는 코드를 만들어 봅니다. 에러발생은 편의상 고려하지 않습니다. 설명은 주석에 달았습니다.
# 파일을 열고 파일을 위한 채널 ID를 변수 f에 넣습니다
# "r"은 읽기를 목적으로 한다는 뜻입니다
set f [open srcfile.txt r]
# 연 파일에서 gets 명령으로 한 줄을 읽어서 변수 buffer에 저장합니다
set buffer [gets $f]
# eof는 파일의 끝인지를 질의하는 명령입니다
# 파일의 끝에 도달하기 전까지 계속 반복작업합니다.
while {![eof $f]} {
# 읽은 행을 콘솔에 출력합니다
puts $buffer
# 한 줄의 텍스트를 읽어들입니다
set buffer [gets $f]
}
# 파일을 닫습니다
close $f
이번엔 소스파일에서 한 줄씩 읽어 타깃파일에 써서 텍스트 파일을 복사하는 코드를 작성합니다.
set f1 [open srcfile.txt r]
# 쓰기를 위하여 파일을 연다
set f2 [open tgtfile.txt w]
set buffer [gets $f1]
while {![eof $f1]} {
# 파일에 한 행을 씁니다
puts $f2 $buffer
set buffer [gets $f1]
}
close $f1
close $f2
한 글자씩 읽어서 쓰는 경우에는 이렇게 합니다. 지정한 바이트만큼을 읽을 때엔 read 명령을 씁니다.
set f1 [open srcfile.txt r]
set f2 [open tgtfile.txt w]
# 한 글자를 읽어 변수 buffer에 저장합니다
set buffer [read $f1 1]
while {![eof $f1]} {
# 파일에 한 글자를 씁니다
# 한 글자 뒤에 줄바꿈 문자를 넣지 않기 위해 "-nonewline" 옵션을 붙입니다
puts -nonewline $f2 $buffer
# 한 글자를 읽습니다
set buffer [read $f1 1]
}
close $f1
close $f2
임의적 접근
작업을 위해 파일을 열면 이 파일은 파일의 내용에 대한 접근위치(access location)를 갖는데 이는 작업이 이루어질 위치를
말하는 것입니다. 그 위치는 파일의 첫 부분으로부터 몇 바이트 떨어져 있나로 표시하는 옵셋(offset)으로 나타냅니다. 파일을 처음 열었을 때 위치가 옵셋값 0에 있으며 작업에 따라 이동합니다.
아래의 코드는 텍스트파일의 각 행의 첫머리의 옵셋값을 구합니다. 텍스트파일을 읽어 들이면서 파일 내에서의 각 행의 첫 글자의 위치를 리스트 offset에 저장합니다. 파일의 접근위치의 옵셋값을 알아내는데 tell 명령을 씁니다.
set f [open srcfile.txt r]
# 옵셋값을 저장할 리스트 offsets를 만듭니다
set offsets {}
# tell 명령으로 알아낸 옵셋값을 리스트 offsets에 덧붙입니다
lappend offsets [tell $f]
set buffer [gets $f]
while {![eof $f]} {
puts $buffer
lappend offsets [tell $f]
set buffer [gets $f]
}
close $f
puts $offsets
이렇게 하면 리스트 offsets엔 옵셋값들이 저장되는데 가장 마지막 요소는 파일 끝의 옵셋값이 되며 이는 곧 그 파일의 크기와 같습니다.
원하는 옵셋의 위치에 바로 접근하려면 seek 명령을 사용합니다. 아래는 파일을 열고 옵셋 100에 바로 가서 한 행의 텍스트를 읽는 코드의 예입니다. 파일 가장 첫머리의 옵셋값이 0인 것에 주의하십시오.
set f [open srcfile.txt r]
# 연 파일의 접근위치를 옵셋 100으로 옮긴다
seek $f 100
set buffer [gets $f]
puts $buffer
close $f