이진파일 레코드 정의
랜덤처리를 위해 코드모듈에 사용자정의 데이터형을 지정하여 일정한 레코드 길이를 다음과 같이 지정했다.
type person '사용자정의 데이터형 정의
number as integer
name as string * 10
mark as integer
end type
person데이터형은 총 14바이트로 언제나 같은 길이를 가지게 된다. 즉, person.name에 영문 2문자만 할당해도 10바이트를 차지하기 때문에 디스크의 낭비를 초래한다. 그러므로 이진처리에서 사용자정의 데이터형을 다음과 같이 지정하도록 한다.
type person
number as integer
name as string '알 수 없는 길이의 name필드정의
mark as integer
end type
이진처리에서 지정한 사용자정의 데이터형 person은 총 (4+a)바이트이다. 왜냐하면, name요소에 할당한 영문의 길이만큼 변하기 때문이다. 예를 들어 person.name="vb"를 넣으면 person.name길이는 2바이트로 지정되어 총 6바이트의 크기가 되므로 랜덤처리에서 쓴 사용자정의형보다 훨씬 더 디스크를 효율적으로 사용할 수 있다.
이진테이터 입력과 읽기
이진처리를 위해 파일을 열 때는 다음과 같은 open문을 사용한다.
open pathname for binary as filenumber
이진엑세스를 위한 open은 랜덤엑세스를 위한 open과 달리 len = recLength가 지정되어 있지 않다. 이진처리 open문에 레코드길이를 포함시켜도 그 것은 무시된다. 프로그램 변수에서 이진파일에 레코드를 저장할 때에도 랜덤처리때 사용한 put문을 사용한다. 이때 실제로 소요된 바이트 수만큼 파일에 저장되므로, 나중에 이 레코드를 읽을 때 길이를 지정해 주어야 한다. 그러기 위해서는 저장되는 문자열의 길이가 얼마인지 알아야 할 필요가 있다. 이러한 문제를 해결하기 위해서는 문자열의 길이를 하나의 정수형 변수에 저장한 다음, 문자열을 저장하기 전에 이 정수형 변수의 값을 저장해야 한다.
다음 예문은 이진처리를 위해 open문으로 파일을 열고, put문을 사용해 데이터를 저장시키는 코드를 나타내고 있다.
코드모듈의 소스코드
Type person
number As Integer
name As String
degree As Integer
End Type
Public student As person
폼모듈의 소스코드
Private Sub cmdAddRecord_Click()
Dim fileNum, strSize As Integer
fileNum = FreeFile
Open "c:\my documents\binary.dat" For Binary As fileNumstudent.number = 1
student.name = "visual"
student.degree = 100strSize = Len(student.number) '필드의 크기를 구한다.
Put #fileNum, , strSize '필드크기만큼 데이터를 파일에 저장한다.
strSize = Len(student.name)
Put #fileNum, , strSize
strSize = Len(student.degree)
Put #fileNum, , strSizeClose #fileNum
End Sub
이진처리시 put문은 [레코드위치]인수가 없다는 것이다. 왜냐하면 이진파일은 순차적으로 데이터를 읽기 때문이다. 데이터를 저장할 위치를 지정하지 않아도 비주얼베이직은 자동적으로 그 위치를 지정해준다. 저장된 파일의 데이터는 get문을 사용하여 역으로 처리하면 된다.
Private Sub cmdReadRecord_Click()
Dim fileNum, strSize As Integer
fileNum = FreeFile
Open "c:\my documents\binary.dat" For Binary As fileNumstrSize = Len(student.number)
Get fileNum, , strSize
strSize = Len(student.name)
Get fileNum, , strSize
strSize = Len(student.degree)
Get fileNum, , strSizeDebug.Print student.number; ; student.name; ; student.degree
Close #fileNum
End Sub
get문 역시 put문처럼 데이터를 순차적으로 읽기 때문에 [레코드위치]를 지정하지 않아도 된다. 그래서, 특정레코드를 직접 찾는 방법은 없으며, 레코드를 읽기 위해서는 반드시 각 레코드의 길이를 알아야 한다.