– Szia Amigo!

"Szia, Bilaabo! Milyen az élet?"

"Remek. Tegnap megpróbáltam megszabadulni néhány parazitától, de eddig nem sok sikerrel jártam. Aztán megint a szemetesben kellett töltenem az éjszakát."

– Szóval... még mindig minden remek?

"Mondhatnád azt is, hogy."

– Jó. Szóval mit hozol nekem ma?

"Ma a RandomAccessFile osztályról fogok mesélni ."

RandomAccessFile stb. – 1

"A helyzet az, hogy a FileInputStream és a FileOutputStream a fájlokat adatfolyamként jeleníti meg: csak egymás után lehet olvasni és írni."

"Ez nem mindig túl kényelmes. Néha írnod ​​kell pár sort egy fájl közepére, vagy néhány oldalnyi szöveget kell olvasnod egy több megabájtos fájl végéről. Nem lenne túl hatékony az olvasás a teljes fájl ezekhez a feladatokhoz."

"A RandomAccessFile osztály ennek a problémának a megoldására jött létre. Ezzel a fájlban bárhová írhatsz, olvashatsz belőle, valamint egyidejűleg olvashatsz és írhatsz a fájlba."

"Milyen érdekes!"

– Igen. Valójában nagyon kényelmes.

– De hogyan lehet tetszőleges helyről olvasni?

"Minden nagyon egyszerű. Képzelje el, hogy meg van nyitva egy szövegszerkesztő, például a Jegyzettömb. Van benne kurzor. Ha beír valamit, a szöveg hozzáadódik a kurzor helyére. A fájl olvasása ugyanaz. Az olvasás innen indul bárhol is legyen a "kurzor". Olvasás/írás közben a kurzor automatikusan mozog."

"Íme, jobb, ha mutatok egy példát:"

Fájl olvasása:
// 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();

"Ebben a példában két dologra szeretném felhívni a figyelmet:"

"Először a RandomAccessFile objektum létrehozása . A második argumentum az r betű. Ez azt jelenti, hogy a fájl olvasásra megnyílik ( r - read ). Ha meg akar nyitni egy fájlt olvasásra és írásra, akkor át kell adnia az « rw-t » a kivitelezőnek, csak az « r » helyett."

"Másodszor nézze meg a keresési módszert. Ezzel a módszerrel körbeugorhatja a fájlt, és megváltoztathatja a kurzor pozícióját az aktuális olvasási/írási művelethez. A fájl első megnyitásakor a kurzor a 0. bájtra áll. Vagy, pontosabban a nulladik bájt előtt."

"Jól értettem? Megnyitjuk a fájlt, és a kurzor a legelején van - a 0. pozícióban. Ezután meghívjuk a seek-t , és a kurzort a 100. bájtig mozgatjuk. És amikor meghívjuk a readLine-t , akkor a századik bájttól kezdi az olvasást. . Jobb?"

"Igen. De szeretném felhívni a figyelmet arra, hogy a keresési módszer lehetővé teszi, hogy tetszőlegesen ugráljon a fájl körül. Például:"

Fájl olvasása:
// 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();

"Ebben a példában először egy 0. bájttal kezdődő sort olvasunk. Utána ugrunk a századik bájtra, és ott beolvasunk egy sort. Utána ismét a 0. bájtra ugrunk, és olvasunk egy sort. Ez azt jelenti, hogy a szöveg1 és a szöveg3 azonos húrok."

– Ah. Ez világosabbá teszi a dolgokat.

"Remek. Akkor itt egy másik példa:"

Fájl olvasása:
// 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();

"Itt megnyitjuk a fájlt olvasásra és írásra az « rw » ( read/write ) átadásával a konstruktornak."

"Ezután azt írjuk a fájlba, hogy " Ez egy karakterlánc ".

"Ezután mozgatjuk a kurzort a 8. bájtra (ami történetesen a "string" szó eleje)"

"Akkor azt írjuk, hogy " meglepetés !"

"Ennek eredményeként a fájl a következőt tartalmazza: " Ez egy meglepetés !"

"Tehát a bájtok nem kerülnek be a fájl közepébe, hanem lecserélik az ott lévőket?"

"Igen."

"Mi van, ha a kurzort a fájl legvégére mozgatjuk?"

"Akkor a bájtok a végére lesznek írva, és a fájl nagyobb lesz. Szóval ez majdnem olyan lenne, mintha szöveget írnánk egy szövegszerkesztőbe."

"Hmm. Azt hiszem, mindent értek. Tudna adni egy teljes listát a RandomAccessFile osztály metódusairól?"

"Persze. Tessék:"

Módszer Leírás
int read() Beolvas egy bájtot, és visszaadja
int read(byte b[], int off, int len) Egy bájttömböt olvas be
int read(byte b[]) Egy bájttömböt olvas be
void readFully(byte b[]) Beolvas egy bájttömböt, és várja az új bájtok hozzáadását, ha nincs elég belőlük a tömb kitöltéséhez
int skipBytes(int n) n bájt kihagyása. Más szóval, ez n bájttal előre mozgatja a kurzort.
void write(int b) Egy bájtot ír a kurzor helyére
void write(byte b[]) Egy bájttömböt ír a kurzor helyére
void write(byte b[], int off, int len) Egy bájttömböt ír a kurzor helyére
long getFilePointer() Annak a bájtnak a számát adja vissza, amelyre a kurzor mutat. 0-tól a fájlhosszig terjedhet
void seek(long pos) Az olvasáshoz/íráshoz használt «kurzort» a megadott helyre mozgatja
long length() A fájl hosszát adja vissza
void setLength(long newLength) Új fájlhosszt állít be. Ha a fájl nagyobb volt, akkor csonkolásra kerül; ha kisebb volt, akkor kibontja a fájlt és az új helyet nullákkal tölti ki
void close() Bezárja a fájlt
boolean readBoolean() Logikai értéket olvas be a kurzor aktuális pozíciójából a fájlban
byte readByte() Beolvas egy bájtot a kurzor aktuális pozíciójából a fájlban
char readChar() Beolvas egy karaktert a kurzor aktuális pozíciójából a fájlban
int readInt() Beolvas egy int a kurzor aktuális pozíciójából a fájlban
long readLong() Hosszú szakaszt olvas be a kurzor aktuális helyétől a fájlban
float readFloat() Beolvas egy lebegőpontot a kurzor aktuális pozíciójából a fájlban
double readDouble() Duplát olvas be a kurzor aktuális pozíciójából a fájlban
String readLine() Beolvas egy sort a fájlból és visszaadja
void writeBoolean(boolean v) Logikai értéket ír a fájlba (a kurzor helyétől kezdve)
void writeByte(int v) t Bájtot ír a fájlba (a kurzor helyétől kezdve)
void writeChar(int v) Egy karaktert ír a fájlba (a kurzor helyétől kezdve)
void writeInt(int v) Egy int-et ír a fájlba (a kurzor helyétől kezdve)
void writeLong(long v) Hosszút ír a fájlba (a kurzor helyétől kezdve)
void writeFloat(float v) Lebegtetést ír a fájlba (a kurzor pozíciójától kezdve)
void writeDouble(double v) Duplát ír a fájlba (a kurzor helyétől kezdve)
void writeBytes(String s) Ír egy karakterláncot a fájlba (a kurzor helyétől kezdve)
void writeChars(String s) Ír egy karakterláncot a fájlba (a kurzor helyétől kezdve)

"Hmm. Szóval nincs itt semmi új. Kivéve talán a seek()/getFilePointer() és a length()/setLength() metóduspárokat."

"Igen, Amigo. Minden körülbelül ugyanaz. De nem kényelmes?"

"Kényelmes. Köszönöm, Bilaabo, az érdekes leckét és a példákat, amiket adott."

– Örülök, hogy segíthetek, Amigo, barátom!