„Hallo, Amigo!“

„Hallo, Bilaabo! Wie ist das Leben?“

„Super. Gestern habe ich versucht, ein paar Parasiten loszuwerden, aber bisher hatte ich keinen großen Erfolg. Und dann musste ich wieder in der Mülltonne übernachten.“

„Also... ist alles noch super?“

"Das könntest du sagen."

„Gut. Was hast du heute für mich?“

„Heute werde ich Ihnen etwas über die RandomAccessFile- Klasse erzählen .“

RandomAccessFile usw. - 1

„Die Sache ist die, dass FileInputStream und FileOutputStream Dateien als Streams darstellen: Sie können sie nur nacheinander lesen und schreiben.“

„Das ist nicht immer besonders praktisch. Manchmal muss man ein paar Zeilen in die Mitte einer Datei schreiben oder ein paar Seiten Text vom Ende einer Multi-Megabyte-Datei lesen. Das wäre nicht sehr effizient zu lesen.“ die gesamte Datei für diese Aufgaben.“

„Die RandomAccessFile- Klasse wurde erstellt, um dieses Problem zu lösen. Sie können damit an einer beliebigen Stelle in die Datei schreiben, daraus lesen sowie gleichzeitig lesen und in die Datei schreiben.“

"Wie interessant!"

„Ja. Eigentlich ist es ganz praktisch.“

„Aber wie liest man von einem beliebigen Ort aus?“

„Es ist alles ziemlich einfach. Stellen Sie sich vor, Sie haben einen Texteditor wie Notepad geöffnet. Er hat einen Cursor. Wenn Sie etwas eingeben, wird der Text an der Stelle eingefügt, an der sich der Cursor befindet. Das Lesen einer Datei ist dasselbe. Das Lesen beginnt bei überall dort, wo sich der „Cursor“ befindet. Beim Lesen/Schreiben bewegt sich der Cursor automatisch.“

„Hier ist es besser, Ihnen ein Beispiel zu zeigen:“

Eine Datei lesen:
// 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 diesem Beispiel möchte ich Sie auf zwei Dinge aufmerksam machen:“

„Zuerst die Erstellung des RandomAccessFile- Objekts. Das zweite Argument ist der Buchstabe r. Dies bedeutet, dass die Datei zum Lesen geöffnet wird ( r – lesen ). Wenn Sie eine Datei zum Lesen und Schreiben öffnen möchten, müssen Sie „ rw “ übergeben » an den Konstruktor, statt nur „ r “.

„Zweitens schauen Sie sich die Suchmethode an. Mit dieser Methode können Sie durch die Datei springen und die Cursorposition für den aktuellen Lese-/Schreibvorgang ändern. Wenn eine Datei zum ersten Mal geöffnet wird, wird der Cursor auf das 0. Byte gesetzt. Oder: genauer gesagt, vor dem nullten Byte.

„Habe ich das richtig verstanden? Wir öffnen die Datei und der Cursor steht ganz am Anfang – an Position 0. Dann rufen wirSeek auf und bewegen den Cursor zum 100. Byte. Und wenn wir readLine aufrufen , beginnt der Lesevorgang ab dem hundertsten Byte . Rechts?"

„Ja. Aber ich möchte Sie darauf aufmerksam machen, dass die Suchmethode es Ihnen ermöglicht, beliebig in der Datei zu springen. Zum Beispiel:“

Eine Datei lesen:
// 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 diesem Beispiel lesen wir zunächst eine Zeile beginnend beim 0. Byte. Dann springen wir zum hundertsten Byte und lesen dort eine Zeile. Anschließend sind wir wieder zum 0. Byte gesprungen und lesen eine Zeile. Das bedeutet, dass text1 und text3 identisch sind.“ Saiten.“

„Ah. Das macht die Sache klarer.“

„Großartig. Dann ist hier noch ein Beispiel:“

Eine Datei lesen:
// 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 öffnen wir die Datei zum Lesen und Schreiben, indem wir „ rw “ ( Lesen/Schreiben ) an den Konstruktor übergeben .“

„Dann schreiben wir „ Es ist eine Zeichenfolge “ in die Datei.

„Dann bewegen wir den Cursor auf das 8. Byte (das zufällig der Anfang des Wortes ‚string‘ ist)“

„Dann schreiben wir: „ Überraschung !““

„Als Ergebnis enthält die Datei: „ Es ist eine Überraschung !““

„Bytes werden also nicht in die Mitte der Datei eingefügt, sondern sie ersetzen diejenigen, die dort waren?“

"Ja."

„Was wäre, wenn wir den Cursor ganz ans Ende der Datei bewegen würden?“

„Dann werden die Bytes bis zum Ende geschrieben und die Datei wird größer. Es wäre also fast so, als würde man Text in einen Texteditor schreiben.“

„Hmm. Ich glaube, ich verstehe alles. Könnten Sie eine vollständige Liste der Methoden der RandomAccessFile- Klasse bereitstellen?“

"Klar, hier bitte:"

Methode Beschreibung
int read() Liest ein Byte und gibt es zurück
int read(byte b[], int off, int len) Liest ein Array von Bytes
int read(byte b[]) Liest ein Array von Bytes
void readFully(byte b[]) Liest ein Array von Bytes und wartet auf das Hinzufügen neuer Bytes, wenn nicht genügend Bytes vorhanden sind, um das Array zu füllen
int skipBytes(int n) Überspringen Sie n Bytes. Mit anderen Worten: Dies bewegt den Cursor um n Bytes vorwärts.
void write(int b) Schreibt ein Byte an die Position des Cursors
void write(byte b[]) Schreibt ein Array von Bytes an die Position des Cursors
void write(byte b[], int off, int len) Schreibt ein Array von Bytes an die Position des Cursors
long getFilePointer() Gibt die Nummer des Bytes zurück, auf das der Cursor zeigt. Der Wert kann zwischen 0 und der Dateilänge liegen
void seek(long pos) Bewegt den zum Lesen/Schreiben verwendeten «Cursor» an die angegebene Stelle
long length() Gibt die Dateilänge zurück
void setLength(long newLength) Legt eine neue Dateilänge fest. Wenn die Datei größer war, wird sie abgeschnitten. Wenn es kleiner war, wird die Datei erweitert und der neue Platz mit Nullen gefüllt
void close() Schließt die Datei
boolean readBoolean() Liest einen booleschen Wert von der aktuellen Position des Cursors in der Datei
byte readByte() Liest ein Byte von der aktuellen Position des Cursors in der Datei
char readChar() Liest ein Zeichen von der aktuellen Position des Cursors in der Datei
int readInt() Liest einen Ganzzahlwert von der aktuellen Position des Cursors in der Datei
long readLong() Liest einen Long-Wert von der aktuellen Position des Cursors in der Datei
float readFloat() Liest einen Float von der aktuellen Position des Cursors in der Datei
double readDouble() Liest ein Double von der aktuellen Position des Cursors in der Datei
String readLine() Liest eine Zeile aus der Datei und gibt sie zurück
void writeBoolean(boolean v) Schreibt einen booleschen Wert in die Datei (beginnend an der Cursorposition).
void writeByte(int v) t Schreibt ein Byte in die Datei (beginnend an der Cursorposition)
void writeChar(int v) Schreibt ein Zeichen in die Datei (beginnend an der Cursorposition)
void writeInt(int v) Schreibt ein int in die Datei (beginnend an der Cursorposition)
void writeLong(long v) Schreibt einen Long-Wert in die Datei (beginnend an der Cursorposition).
void writeFloat(float v) Schreibt einen Float in die Datei (beginnend an der Position des Cursors)
void writeDouble(double v) Schreibt ein Double in die Datei (beginnend an der Cursorposition)
void writeBytes(String s) Schreibt einen String in die Datei (beginnend an der Cursorposition)
void writeChars(String s) Schreibt einen String in die Datei (beginnend an der Cursorposition)

„Hmm. Hier gibt es also nichts Neues. Außer vielleicht den Methodenpaaren see()/getFilePointer() und length()/setLength().“

„Ja, Amigo. Alles ist ungefähr gleich. Aber ist das nicht praktisch?“

„Das ist praktisch. Danke, Bilaabo, für die interessante Lektion und die Beispiele, die du mir gegeben hast.“

„Freut mich zu helfen, Amigo, mein Freund!“