“สวัสดี อามีโก้!”

"สวัสดี บิลาโบ! เป็นอย่างไรบ้าง"

"เยี่ยมมาก เมื่อวานฉันพยายามกำจัดปรสิตบางตัว แต่จนถึงตอนนี้ฉันยังไม่ประสบความสำเร็จมากนัก จากนั้นฉันก็ต้องค้างคืนในถังขยะอีกครั้ง"

“แล้ว...ทุกอย่างยังดีอยู่หรือเปล่า?”

"พูดแบบนั้นก็ได้"

“ดี แล้ววันนี้คุณมีอะไรจะให้ฉันบ้าง”

"วันนี้ฉันจะบอกคุณเกี่ยวกับ คลาส RandomAccessFile "

RandomAccessFile เป็นต้น - 1

"สิ่งนี้คือ FileInputStream และ FileOutputStream แสดงไฟล์เป็นสตรีม: คุณสามารถอ่านและเขียนตามลำดับเท่านั้น"

"นั่นไม่สะดวกเสมอไป บางครั้งคุณต้องเขียนสองสามบรรทัดตรงกลางไฟล์ หรืออ่านข้อความสองสามหน้าจากส่วนท้ายของไฟล์หลายเมกะไบต์ การอ่านจะไม่มีประสิทธิภาพมากนัก ไฟล์ทั้งหมดสำหรับงานเหล่านี้"

" คลาส RandomAccessFileถูกสร้างขึ้นเพื่อแก้ปัญหานี้ คุณสามารถใช้คลาสนี้เพื่อเขียนที่ใดก็ได้ในไฟล์ อ่านจากมัน ตลอดจนอ่านและเขียนไฟล์ในเวลาเดียวกัน"

"น่าสนใจจัง!"

"ใช่ มันค่อนข้างสะดวกจริงๆ"

"แต่คุณอ่านจากตำแหน่งโดยพลการได้อย่างไร"

"ทุกอย่างค่อนข้างเรียบง่าย ลองนึกภาพว่าคุณมีโปรแกรมแก้ไขข้อความ เช่น Notepad เปิดอยู่ มันมีเคอร์เซอร์ เมื่อคุณพิมพ์ข้อความ ข้อความจะถูกเพิ่มไปยังตำแหน่งใดก็ตามที่เคอร์เซอร์อยู่ การอ่านไฟล์ก็เหมือนกัน การอ่านเริ่มจาก ไม่ว่า 'เคอร์เซอร์' จะอยู่ที่ไหน เมื่ออ่าน/เขียน เคอร์เซอร์จะเลื่อนโดยอัตโนมัติ"

"นี่จะเป็นการดีกว่าถ้าจะแสดงตัวอย่าง:"

อ่านไฟล์:
// 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 - อ่าน ) หากคุณต้องการเปิดไฟล์เพื่ออ่านและเขียน คุณต้องผ่าน « rw » ให้กับตัวสร้าง แทนที่จะเป็นแค่ « r »"

"ประการที่สอง ดูที่วิธีการค้นหา คุณสามารถใช้วิธีนี้เพื่อข้ามไปรอบๆ ไฟล์และเปลี่ยนตำแหน่งเคอร์เซอร์สำหรับการดำเนินการอ่าน/เขียนปัจจุบัน เมื่อเปิดไฟล์ครั้งแรก เคอร์เซอร์จะถูกตั้งค่าเป็นไบต์ที่ 0 หรือ แม่นยำยิ่งขึ้น ก่อนไบต์ที่ศูนย์"

"ฉันเข้าใจถูกต้องหรือไม่ เราเปิดไฟล์และเคอร์เซอร์อยู่ที่จุดเริ่มต้น - ที่ตำแหน่ง 0 จากนั้นเราเรียกค้นหาและเลื่อนเคอร์เซอร์ไปที่ไบต์ที่ 100 และเมื่อเราเรียกreadLineมันจะเริ่มอ่านจากไบต์ที่ร้อย . ขวา?"

"ใช่ แต่ฉันต้องการดึงความสนใจของคุณไปที่ข้อเท็จจริงที่ว่าวิธีการค้นหาอนุญาตให้คุณข้ามไปรอบๆ ไฟล์โดยพลการ ตัวอย่างเช่น:"

อ่านไฟล์:
// 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 จากนั้นเราข้ามไปที่ไบต์ที่ร้อยและอ่านบรรทัดตรงนั้น จากนั้นเราข้ามไปที่ไบต์ที่ 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 (ซึ่งเป็นจุดเริ่มต้นของคำว่า 'string')"

"จากนั้นเราเขียนว่า « เซอร์ไพรส์ !»"

"ด้วยเหตุนี้ ไฟล์จึงมี « เป็นเรื่องที่น่าประหลาดใจ !»"

"ดังนั้น ไบต์จะไม่ถูกแทรกลงตรงกลางไฟล์ แต่จะแทนที่ไบต์ที่อยู่ตรงนั้น"

"ใช่."

"จะเกิดอะไรขึ้นถ้าเราเลื่อนเคอร์เซอร์ไปที่ท้ายสุดของไฟล์"

"จากนั้นไบต์จะถูกเขียนจนจบ และไฟล์จะใหญ่ขึ้น ดังนั้นมันเกือบจะเหมือนกับการเขียนข้อความลงในโปรแกรมแก้ไขข้อความ"

"อืม ฉันคิดว่าฉันเข้าใจทุกอย่างแล้ว คุณช่วยระบุรายการเมธอดของคลาสRandomAccessFile ทั้งหมดได้ไหม"

"ได้เลย เอาล่ะ:"

วิธี คำอธิบาย
int read() อ่านหนึ่งไบต์และส่งคืน
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) เขียนหนึ่งไบต์ไปยังตำแหน่งของเคอร์เซอร์
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) กำหนดความยาวไฟล์ใหม่ หากไฟล์มีขนาดใหญ่ขึ้น ไฟล์นั้นจะถูกตัดทอน ถ้ามันเล็กลง มันจะขยายไฟล์และเติมช่องว่างใหม่ด้วยศูนย์
void close() ปิดไฟล์
boolean readBoolean() อ่านบูลีนจากตำแหน่งปัจจุบันของเคอร์เซอร์ในไฟล์
byte readByte() อ่านไบต์จากตำแหน่งปัจจุบันของเคอร์เซอร์ในไฟล์
char readChar() อ่านอักขระจากตำแหน่งปัจจุบันของเคอร์เซอร์ในไฟล์
int readInt() อ่าน int จากตำแหน่งปัจจุบันของเคอร์เซอร์ในไฟล์
long readLong() อ่านยาวจากตำแหน่งปัจจุบันของเคอร์เซอร์ในไฟล์
float readFloat() อ่านทศนิยมจากตำแหน่งปัจจุบันของเคอร์เซอร์ในไฟล์
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) เขียนไฟล์ยาว (เริ่มจากตำแหน่งเคอร์เซอร์)
void writeFloat(float v) เขียนทศนิยมลงในไฟล์ (เริ่มจากตำแหน่งเคอร์เซอร์)
void writeDouble(double v) เขียนสองครั้งในไฟล์ (เริ่มจากตำแหน่งของเคอร์เซอร์)
void writeBytes(String s) เขียนสตริงลงในไฟล์ (เริ่มจากตำแหน่งเคอร์เซอร์)
void writeChars(String s) เขียนสตริงลงในไฟล์ (เริ่มจากตำแหน่งเคอร์เซอร์)

"อืม ไม่มีอะไรใหม่ที่นี่ ยกเว้นอาจจะเป็นคู่ของวิธีการ ask()/getFilePointer() และ length()/setLength()"

“ใช่ อามีโก้ ทุกอย่างก็เหมือนเดิม แต่ไม่สะดวกอย่างนั้นเหรอ?”

"สะดวก ขอบคุณ Bilaabo สำหรับบทเรียนที่น่าสนใจและตัวอย่างที่คุณให้ฉัน"

"ยินดีที่ได้ช่วย อามีโก้ เพื่อนของฉัน!"