"Ciao, Amico!"
"Ciao, Bilaabo! Come va la vita?"
"Fantastico. Ieri ho provato a sbarazzarmi di alcuni parassiti, ma finora non ho avuto molto successo. E poi ho dovuto passare di nuovo la notte nel bidone della spazzatura."
"Allora... va ancora tutto bene?"
"Potresti dire che."
"Bene. Allora cosa hai per me oggi?"
"Oggi ti parlerò della classe RandomAccessFile ."
"Il fatto è che FileInputStream e FileOutputStream rappresentano i file come flussi: puoi solo leggerli e scriverli in sequenza."
"Non è sempre super conveniente. A volte è necessario scrivere un paio di righe nel mezzo di un file o leggere un paio di pagine di testo dalla fine di un file multi-megabyte. Non sarebbe molto efficiente leggere l'intero file per queste attività."
"La classe RandomAccessFile è stata creata per risolvere questo problema. Puoi usarla per scrivere ovunque nel file, leggere da esso, così come leggere e scrivere nel file allo stesso tempo."
"Interessante!"
"Sì. In realtà è abbastanza comodo."
"Ma come si fa a leggere da una posizione arbitraria?"
"È tutto piuttosto semplice. Immagina di avere un editor di testo, come Blocco note, aperto. Ha un cursore. Quando digiti qualcosa, il testo viene aggiunto ovunque si trovi il cursore. La lettura di un file è la stessa. La lettura inizia da ovunque si trovi il "cursore". Durante la lettura/scrittura, il cursore si sposta automaticamente."
"Ecco, sarà meglio mostrarti un esempio:"
// 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 questo esempio, vorrei attirare la tua attenzione su due cose:"
"In primo luogo, la creazione dell'oggetto RandomAccessFile . Il secondo argomento è la lettera r. Ciò significa che il file è aperto per la lettura ( r - read ). Se si desidera aprire un file per la lettura e la scrittura, è necessario passare « rw » al costruttore, invece che solo « r »."
"In secondo luogo, osserva il metodo di ricerca. Puoi utilizzare questo metodo per saltare all'interno del file e modificare la posizione del cursore per l'operazione di lettura/scrittura corrente. Quando un file viene aperto per la prima volta, il cursore è impostato sullo 0° byte. Oppure, più precisamente, prima dello zeroesimo byte."
"Ho capito bene? Apriamo il file e il cursore si trova proprio all'inizio, nella posizione 0. Quindi chiamiamo seek e spostiamo il cursore al centesimo byte. E quando chiamiamo readLine , inizia a leggere dal centesimo byte . Giusto?"
"Sì. Ma voglio attirare la tua attenzione sul fatto che il metodo di ricerca ti consente di saltare arbitrariamente all'interno del file. Ad esempio:"
// 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 questo esempio, prima leggiamo una riga che inizia dal byte 0. Quindi saltiamo al centesimo byte e leggiamo una riga lì. Quindi saltiamo di nuovo allo 0 byte e leggiamo una riga. Ciò significa che testo1 e testo3 sono identici stringhe."
"Ah. Questo rende le cose più chiare."
"Fantastico. Allora ecco un altro esempio:"
// 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();
"Qui apriamo il file per la lettura e la scrittura passando « rw » ( read/write ) al costruttore."
"Poi scriviamo « È una stringa » nel file.
"Quindi spostiamo il cursore sull'ottavo byte (che risulta essere l'inizio della parola 'stringa')"
"Poi scriviamo « sorpresa !»"
"Di conseguenza, il file contiene « È una sorpresa !»"
"Quindi, i byte non vengono inseriti nel mezzo del file, ma piuttosto sostituiscono quelli che c'erano?"
"Sì."
"E se spostiamo il cursore fino alla fine del file?"
"Quindi i byte verranno scritti fino alla fine e il file diventerà più grande. Quindi sarebbe quasi come scrivere del testo in un editor di testo."
"Hmm. Penso di aver capito tutto. Potresti fornire un elenco completo dei metodi della classe RandomAccessFile ?"
"Certo, ecco a te:"
Metodo | Descrizione |
---|---|
int read() |
Legge un byte e lo restituisce |
int read(byte b[], int off, int len) |
Legge un array di byte |
int read(byte b[]) |
Legge un array di byte |
void readFully(byte b[]) |
Legge un array di byte e attende l'aggiunta di nuovi byte se non ce ne sono abbastanza per riempire l'array |
int skipBytes(int n) |
Salta n byte. In altre parole, questo sposta il cursore in avanti di n byte. |
void write(int b) |
Scrive un byte nella posizione del cursore |
void write(byte b[]) |
Scrive una matrice di byte nella posizione del cursore |
void write(byte b[], int off, int len) |
Scrive una matrice di byte nella posizione del cursore |
long getFilePointer() |
Restituisce il numero del byte a cui punta il cursore. Può variare da 0 alla lunghezza del file |
void seek(long pos) |
Sposta il «cursore» utilizzato per la lettura/scrittura nella posizione specificata |
long length() |
Restituisce la lunghezza del file |
void setLength(long newLength) |
Imposta una nuova lunghezza del file. Se il file era più grande, viene troncato; se era più piccolo, espande il file e riempie il nuovo spazio con zeri |
void close() |
Chiude il file |
boolean readBoolean() |
Legge un valore booleano dalla posizione corrente del cursore nel file |
byte readByte() |
Legge un byte dalla posizione corrente del cursore nel file |
char readChar() |
Legge un carattere dalla posizione corrente del cursore nel file |
int readInt() |
Legge un int dalla posizione corrente del cursore nel file |
long readLong() |
Legge un long dalla posizione corrente del cursore nel file |
float readFloat() |
Legge un float dalla posizione corrente del cursore nel file |
double readDouble() |
Legge un double dalla posizione corrente del cursore nel file |
String readLine() |
Legge una riga dal file e la restituisce |
void writeBoolean(boolean v) |
Scrive un valore booleano nel file (a partire dalla posizione del cursore) |
void writeByte(int v) t |
Scrive un byte nel file (a partire dalla posizione del cursore) |
void writeChar(int v) |
Scrive un carattere nel file (partendo dalla posizione del cursore) |
void writeInt(int v) |
Scrive un int nel file (a partire dalla posizione del cursore) |
void writeLong(long v) |
Scrive un lungo nel file (a partire dalla posizione del cursore) |
void writeFloat(float v) |
Scrive un float nel file (a partire dalla posizione del cursore) |
void writeDouble(double v) |
Scrive un double nel file (partendo dalla posizione del cursore) |
void writeBytes(String s) |
Scrive una stringa nel file (a partire dalla posizione del cursore) |
void writeChars(String s) |
Scrive una stringa nel file (a partire dalla posizione del cursore) |
"Hmm. Quindi, non c'è niente di nuovo qui. Tranne forse le coppie di metodi seek()/getFilePointer() e length()/setLength()."
"Sì, Amigo. Tutto è più o meno uguale. Ma non è conveniente?"
"È conveniente. Grazie, Bilaabo, per l'interessante lezione e per gli esempi che mi hai fornito."
"Lieto di aiutarti, Amigo, amico mio!"
GO TO FULL VERSION