"Hallo Amigo!"

"Hallo, Bilaabo! Hoe is het leven?"

"Geweldig. Gisteren heb ik geprobeerd wat parasieten kwijt te raken, maar tot nu toe heb ik niet veel succes gehad. En toen moest ik weer een nacht in de vuilnisbak doorbrengen."

"Dus... is alles nog goed?"

"Dat zou je kunnen zeggen."

"Goed. Dus wat heb je vandaag voor me?"

"Vandaag zal ik je vertellen over de klasse RandomAccessFile ."

RandomAccessFile, enz. - 1

"Het punt is dat FileInputStream en FileOutputStream bestanden voorstellen als streams: je kunt ze alleen opeenvolgend lezen en ernaar schrijven."

"Dat is niet altijd superhandig. Soms moet je een paar regels schrijven in het midden van een bestand, of een paar pagina's tekst lezen vanaf het einde van een bestand van meerdere megabytes. Het zou niet erg efficiënt zijn om het hele bestand voor deze taken."

"De klasse RandomAccessFile is gemaakt om dit probleem op te lossen. Je kunt het gebruiken om overal in het bestand te schrijven, ervan te lezen en tegelijkertijd naar het bestand te lezen en ernaar te schrijven."

"Hoe interessant!"

"Ja. Het is eigenlijk best handig."

"Maar hoe lees je vanaf een willekeurige locatie?"

"Het is allemaal vrij eenvoudig. Stel je voor dat je een teksteditor, zoals Kladblok, hebt geopend. Het heeft een cursor. Als je iets typt, wordt de tekst toegevoegd aan waar de cursor zich bevindt. Het lezen van een bestand is hetzelfde. Lezen begint vanaf waar de 'cursor' ook staat. Bij het lezen/schrijven beweegt de cursor automatisch."

"Hier, het is beter om u een voorbeeld te laten zien:"

Een bestand lezen:
// 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();

"In dit voorbeeld wil ik uw aandacht vestigen op twee dingen:"

"Ten eerste de aanmaak van het RandomAccessFile- object. Het tweede argument is de letter r. Dit betekent dat het bestand wordt geopend om te lezen ( r - read ). Als u een bestand wilt openen om te lezen en te schrijven, moet u « rw doorgeven » naar de constructor, in plaats van alleen « r »."

"Ten tweede, kijk naar de zoekmethode. U kunt deze methode gebruiken om door het bestand te springen en de cursorpositie te wijzigen voor de huidige lees-/schrijfbewerking. Wanneer een bestand voor het eerst wordt geopend, wordt de cursor ingesteld op de 0e byte. Of, nauwkeuriger, vóór de nulde byte."

"Heb ik het goed begrepen? We openen het bestand en de cursor staat helemaal aan het begin - op positie 0. Vervolgens roepen we zoeken op en verplaatsen we de cursor naar de 100e byte. En wanneer we readLine aanroepen , begint het te lezen vanaf de honderdste byte . Rechts?"

"Ja. Maar ik wil uw aandacht vestigen op het feit dat u met de zoekmethode willekeurig door het bestand kunt springen. Bijvoorbeeld:"

Een bestand lezen:
// 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();

"In dit voorbeeld lezen we eerst een regel die begint bij de 0e byte. Dan springen we naar de honderdste byte en lezen daar een regel. Daarna zijn we weer naar de 0e byte gesprongen en lezen we een regel. Dat betekent dat tekst1 en tekst3 identiek zijn snaren."

"Ah. Dat maakt de zaken duidelijker."

"Geweldig. Dan is hier nog een voorbeeld:"

Een bestand lezen:
// 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();

"Hier openen we het bestand voor lezen en schrijven door « rw » ( read/write ) door te geven aan de constructor."

"Vervolgens schrijven we « Het is een string » naar het bestand.

"Vervolgens verplaatsen we de cursor naar de 8e byte (wat toevallig het begin is van het woord 'string')"

"Dan schrijven we « verrassing !»"

"Als gevolg hiervan bevat het bestand « Het is een verrassing ! »"

"Dus, bytes worden niet in het midden van het bestand ingevoegd, maar vervangen de bytes die er al waren?"

"Ja."

"Wat als we de cursor helemaal naar het einde van het bestand verplaatsen?"

"Dan worden de bytes tot het einde geschreven en wordt het bestand groter. Het zou dus bijna zijn alsof je tekst in een teksteditor schrijft."

"Hmm. Ik denk dat ik alles begrijp. Kunt u een volledige lijst geven van de methoden van de klasse RandomAccessFile ?"

"Natuurlijk. Alsjeblieft:"

Methode Beschrijving
int read() Leest één byte en retourneert deze
int read(byte b[], int off, int len) Leest een reeks bytes
int read(byte b[]) Leest een reeks bytes
void readFully(byte b[]) Leest een reeks bytes en wacht tot er nieuwe bytes worden toegevoegd als er niet genoeg zijn om de reeks te vullen
int skipBytes(int n) Sla n bytes over. Met andere woorden, dit verplaatst de cursor n bytes vooruit.
void write(int b) Schrijft één byte naar de locatie van de cursor
void write(byte b[]) Schrijft een reeks bytes naar de locatie van de cursor
void write(byte b[], int off, int len) Schrijft een reeks bytes naar de locatie van de cursor
long getFilePointer() Retourneert het nummer van de byte waarnaar de cursor verwijst. Het kan variëren van 0 tot de bestandslengte
void seek(long pos) Verplaatst de «cursor» die wordt gebruikt voor lezen/schrijven naar de opgegeven locatie
long length() Retourneert de bestandslengte
void setLength(long newLength) Stelt een nieuwe bestandslengte in. Als het bestand groter was, wordt het afgekapt; als het kleiner was, breidt het het bestand uit en vult het de nieuwe ruimte met nullen
void close() Sluit het bestand
boolean readBoolean() Leest een Booleaanse waarde van de huidige positie van de cursor in het bestand
byte readByte() Leest een byte van de huidige positie van de cursor in het bestand
char readChar() Leest een teken van de huidige positie van de cursor in het bestand
int readInt() Leest een int vanaf de huidige positie van de cursor in het bestand
long readLong() Leest een lange afstand vanaf de huidige positie van de cursor in het bestand
float readFloat() Leest een float vanaf de huidige positie van de cursor in het bestand
double readDouble() Leest een dubbel van de huidige positie van de cursor in het bestand
String readLine() Leest een regel uit het bestand en retourneert deze
void writeBoolean(boolean v) Schrijft een boolean naar het bestand (beginnend vanaf de positie van de cursor)
void writeByte(int v) t Schrijft een byte naar het bestand (beginnend vanaf de positie van de cursor)
void writeChar(int v) Schrijft een teken naar het bestand (beginnend vanaf de positie van de cursor)
void writeInt(int v) Schrijft een int naar het bestand (beginnend vanaf de positie van de cursor)
void writeLong(long v) Schrijft een long naar het bestand (beginnend vanaf de positie van de cursor)
void writeFloat(float v) Schrijft een float naar het bestand (beginnend vanaf de positie van de cursor)
void writeDouble(double v) Schrijft een double naar het bestand (beginnend vanaf de positie van de cursor)
void writeBytes(String s) Schrijft een tekenreeks naar het bestand (beginnend vanaf de positie van de cursor)
void writeChars(String s) Schrijft een tekenreeks naar het bestand (beginnend vanaf de positie van de cursor)

"Hmm. Er is hier dus niets nieuws. Behalve misschien de combinaties seek()/getFilePointer() en length()/setLength()."

"Ja, Amigo. Alles is ongeveer hetzelfde. Maar is dat niet handig?"

"Het is handig. Dank je, Bilaabo, voor een interessante les en voor de voorbeelden die je me gaf."

"Blij om te helpen, Amigo, mijn vriend!"