"안녕, 아미고!"

"안녕, Bilaabo! 생활은 어때?"

"좋아요. 어제 기생충 몇 마리를 박멸하려고 했는데 지금까지 별 성과가 없었어요. 그리고 또 쓰레기통에서 밤을 지새워야 했어요."

"그럼... 아직 괜찮나요?"

"당신은 그렇게 말할 수 있습니다."

"좋습니다. 오늘은 무엇을 드릴까요?"

"오늘은 RandomAccessFile 클래스 에 대해 알려드리겠습니다 ."

RandomAccessFile 등 - 1

"문제는 FileInputStream과 FileOutputStream이 파일을 스트림으로 표현한다는 것입니다. 순차적으로만 읽고 쓸 수 있습니다."

"항상 매우 편리한 것은 아닙니다. 때로는 파일 중간에 몇 줄을 작성하거나 멀티 메가바이트 파일의 끝에서 몇 페이지의 텍스트를 읽어야 합니다. 읽기에는 그다지 효율적이지 않습니다. 이러한 작업에 대한 전체 파일."

" RandomAccessFile 클래스는 이 문제를 해결하기 위해 만들어졌습니다. 이 클래스를 사용하여 파일의 아무 위치에나 쓰고, 읽고, 동시에 파일을 읽고 쓸 수 있습니다."

"얼마나 흥미로운가!"

"네. 꽤 편리합니다."

"하지만 임의의 위치에서 어떻게 읽습니까?"

"모든 것이 매우 간단합니다. 메모장과 같은 텍스트 편집기가 열려 있다고 상상해보십시오. 커서가 있습니다. 무언가를 입력하면 커서가 있는 곳에 텍스트가 추가됩니다. 파일 읽기는 동일합니다. 읽기는 '커서'가 있는 곳 어디든지. 읽기/쓰기 시 커서가 자동으로 이동합니다."

"여기서 예를 보여드리는 것이 좋습니다."

파일 읽기:
// r - read, the file is opened only for reading.
RandomAccessFile raf = new RandomAccessFile("input.txt", "r");

// Move the «cursor» to the 100th character.
raf.seek(100);

// Read the line starting from the current cursor position until the end of the line.
String text = raf.readLine();

// Close the file.
raf.close();

"이 예에서는 다음 두 가지에 주의를 기울이고 싶습니다."

"첫째, RandomAccessFile 개체 의 생성입니다 . 두 번째 인수는 문자 r입니다. 이것은 파일이 읽기용으로 열려 있음을 의미합니다( r - read ). 읽기 및 쓰기용으로 파일을 열려면 « rw를 전달해야 합니다. »는 단지 « r » 대신 생성자에게 전달됩니다 ."

"둘째, 검색 방법을 살펴보십시오. 이 방법을 사용하여 파일 주위를 이동하고 현재 읽기/쓰기 작업에 대한 커서 위치를 변경할 수 있습니다. 파일이 처음 열릴 때 커서는 0번째 바이트로 설정됩니다. 또는, 더 정확하게는 0번째 바이트 이전입니다."

"제대로 이해했나요? 파일을 열면 커서가 맨 처음 위치인 0에 있습니다. 그런 다음 seek를 호출하고 커서 를 100번째 바이트로 이동합니다. 그리고 readLine을 호출하면 100번째 바이트부터 읽기 시작합니다. . 오른쪽?"

"예. 하지만 검색 방법을 사용하면 파일 주위를 임의로 이동할 수 있다는 사실에 주의를 기울이고 싶습니다. 예를 들면 다음과 같습니다."

파일 읽기:
// r - read, the file is opened only for reading.
RandomAccessFile raf = new RandomAccessFile("input.txt", "r");

// The "cursor" is at the 0th character.
String text1 = raf.readLine();

// Move the "cursor" to the 100th character.
raf.seek(100);
String text2 = raf.readLine();

// Move the "cursor" to the 0th character.
raf.seek(0);
String text3 = raf.readLine();

// Close the file
raf.close();

"이 예에서는 먼저 0번째 바이트에서 시작하는 라인을 읽습니다. 그런 다음 100번째 바이트로 점프하여 거기에서 라인을 읽습니다. 그런 다음 다시 0번째 바이트로 점프하여 라인을 읽습니다. 즉, text1과 text3은 동일합니다. 문자열."

"아. 그러면 일이 더 명확해집니다."

"좋습니다. 그럼 여기 또 다른 예가 있습니다."

파일 읽기:
// rw - read/write, the file is opened for reading and writing.
RandomAccessFile raf = new RandomAccessFile("seek.txt", "rw");

// Write to the file, starting from the 0th byte.
raf.writeBytes("It is a string");

// Move the "cursor" to the 8th character.
raf.seek(8);

// Write "surprise!" to the file.
raf.writeBytes("surprise!");

// Close the file.
raf.close();

"여기서 « rw »( 읽기/쓰기 )를 생성자에 전달하여 읽기 및 쓰기용 파일을 엽니다 ."

"그런 다음 파일에 « 그것은 문자열입니다 » 라고 씁니다 .

"그런 다음 커서를 8번째 바이트('문자열'이라는 단어의 시작 부분)로 이동합니다."

"그런 다음 « 놀람 !» 이라고 씁니다. "

"결과적으로 파일에는 « 놀랍습니다 !»"가 포함되어 있습니다.

"그래서 바이트는 파일 중간에 삽입되지 않고 거기에 있던 바이트를 대체합니까?"

"네."

"파일 맨 끝으로 커서를 이동하면 어떻게 됩니까?"

"그러면 바이트가 끝까지 기록되고 파일이 더 커질 것입니다. 따라서 텍스트 편집기에 텍스트를 쓰는 것과 거의 같습니다."

"흠. 모든 것을 이해한 것 같습니다. RandomAccessFile 클래스의 전체 메서드 목록을 제공할 수 있습니까?"

"물론입니다. 여기 있습니다:"

방법 설명
int read() 1바이트를 읽고 반환
int read(byte b[], int off, int len) 바이트 배열을 읽습니다.
int read(byte b[]) 바이트 배열을 읽습니다.
void readFully(byte b[]) 바이트 배열을 읽고 배열을 채울 만큼 바이트가 충분하지 않은 경우 새 바이트가 추가될 때까지 기다립니다.
int skipBytes(int n) n바이트를 건너뜁니다. 즉, 커서를 n바이트 앞으로 이동합니다.
void write(int b) 커서 위치에 1바이트 쓰기
void write(byte b[]) 커서 위치에 바이트 배열을 씁니다.
void write(byte b[], int off, int len) 커서 위치에 바이트 배열을 씁니다.
long getFilePointer() 커서가 가리키는 바이트 수를 반환합니다. 0부터 파일 길이까지 가능합니다.
void seek(long pos) 읽기/쓰기에 사용되는 «커서»를 지정된 위치로 이동
long length() 파일 길이를 반환
void setLength(long newLength) 새 파일 길이를 설정합니다. 파일이 더 크면 잘립니다. 더 작은 경우 파일을 확장하고 새 공간을 0으로 채웁니다.
void close() 파일을 닫습니다
boolean readBoolean() 파일에서 커서의 현재 위치에서 부울을 읽습니다.
byte readByte() 파일에서 커서의 현재 위치에서 바이트를 읽습니다.
char readChar() 파일에서 커서의 현재 위치에서 문자를 읽습니다.
int readInt() 파일에서 커서의 현재 위치에서 int를 읽습니다.
long readLong() 파일에서 커서의 현재 위치에서 long을 읽습니다.
float readFloat() 파일에서 커서의 현재 위치에서 float를 읽습니다.
double readDouble() 파일에서 커서의 현재 위치에서 더블을 읽습니다.
String readLine() 파일에서 한 줄을 읽고 반환
void writeBoolean(boolean v) 파일에 부울 쓰기(커서 위치에서 시작)
void writeByte(int v) t 파일에 바이트 쓰기(커서 위치에서 시작)
void writeChar(int v) 파일에 문자 쓰기(커서 위치에서 시작)
void writeInt(int v) 파일에 int 쓰기(커서 위치에서 시작)
void writeLong(long v) 파일에 long 쓰기(커서 위치에서 시작)
void writeFloat(float v) 파일에 float 쓰기(커서 위치에서 시작)
void writeDouble(double v) 파일에 double 쓰기(커서 위치에서 시작)
void writeBytes(String s) 파일에 문자열 쓰기(커서 위치에서 시작)
void writeChars(String s) 파일에 문자열 쓰기(커서 위치에서 시작)

"흠. 그래서 여기에는 새로운 것이 없습니다. seek()/getFilePointer() 및 length()/setLength() 메서드 쌍을 제외하고 말입니다."

"네, 아미고. 모든 것이 다 비슷비슷합니다. 하지만 그게 편리하지 않습니까?"

"편리합니다. Bilaabo, 흥미로운 교훈과 예를 들어 주셔서 감사합니다."

"도와줘서 기뻐, 친구 아미고!"