자바/입출력 IO

표준 입출력과 File: RandomAccessFile

백_곰 2022. 4. 27. 14:49

1. RandomAccessFile

- 자바에서는 입력과 출력이 각각 분리되어 별도로 작업을 하도록 설계되어 있는데,

 RandomAccessFile만은 하나의 클래스로 입력과 출력을 모두 할 수 있도록 되어 있다.

 

- RandomAccessFile은 InputSteam과 OutputStream으로부터 상속받지 않고, DataInput 인터페이스

DataOutput 인터페이스를 모두 구현했기 때문에 읽기와 쓰기가 모두 가능하다.

 

- RandomAccessFile 클래스 가장 큰 장점은 파일의 어느 위치에나 읽기/쓰기가 가능하다는 것이다.

( 다른 입출력 클래스들은 입출력 소스에 순착적으로 읽기/쓰기를 하기 때문에 읽기와 쓰기가

제한적이다. )

 

- 그러므로, RandomAccessFile 클래스 어느 위치에 읽기/쓰기를 가능하게 하기 위해서 내부적으로

포인터를 사용하는데, 입출력 시에 작업이 수행되는 곳이 바로 파일 포인터가 위치한 곳이 된다.

 

 

 

- 아래는 RandomAccessFile 클래스의 생성자/메서드를 설명한다.

 

(1) RandomAccessFile(File file, String mode)

또는

RandomAccessFile(String file, String mode)

: 주어진 file에 읽기 또는 읽기/쓰기를 하기 위한 RandomAccessFile 인스턴스를 생성한다.

: mode의 값은 "r", "rw", "rws", "rwd"가 지정가능하다.

( "rwd"는 파일 내용만, "rws"는 파일의 메타정보도 포함해서 출력한다. )

 

(2) FileChannel getChannel()

: 파일의 파일 채널을 반환한다.

 

(3) FileDescriptor getFD()

: 파일의 파일 디스크립터를 반환한다.

 

(4) long getFilePointer()

: 파일의 포인터 위치를 알려준다.

 

(5) long length()

: 파일의 크기를 얻을 수 있다. (byte 단위)

 

(6) void seek(long pos)

: 파일 포인터의 위치를 변경한다.

: 위치는 파일의 첫 부분부터 pos 크기만큼 떨어진 곳이다.

 

(7) void setLLength(long newLength)

: 파일의 크기를 지정된 길이로 변경한다. (byte 단위)

 

(8) int skipBytes(int n)

: 지정된 수만큼의 byte를 건너뛴다.

 

 

 

 

1-1. RandomAccessFile를 이해하기 위한 예제(1)

: 파일에 출력작업이 수행되었을 때 파일 포인터의 위치가 어떻게 달라지는지에 대해서 보여주는

예제이다. 

 

Exercise022

( writeInt()를 쓰면 +4 byte씩, writeLong()를 쓰면 +8 byte씩 늘어나는 것을 볼 수 있다. )

 

 

 

 

1-2. RandomAccessFile를 이해하기 위한 예제(2)

: RandomAccessFile로 파일을 writeInt()로 쓴 다음 readInt()로 읽는 예제이다.

 

Exercise023

( 출력 결과 아무것도 출력되지 않는다. )

( 그 이유는 writeInt()를 수행하면서 파일 포인터의 위치가 파일의 마지막으로 이동되었기 때문이다. )

( 그러므로, 아래의 코드처럼 seek() 메서드를 넣어 다시 파일의 초기위치 0으로 set해주어야 한다. )

 

raf.seek(0); 을 추가한 코드

 

 

 

 

1-3. RandomAccessFile을 이해하기 위한 예제(3)

: 1-2 예제(2)의 파일을 가지고 국어 과목의 점수만을 합계하는 예제이다.

 

Exercise024

( int가 4 byte씩 저장되어 있으므로, 4칸을 당겨서 읽어야 하므로 4*4 = 16만큼 더해줘야 한다. )