« Salut Amigo ! »

« Salut, Bilaabo ! Comment va la vie ?

"Génial. Hier, j'ai essayé de me débarrasser de certains parasites, mais jusqu'à présent, je n'ai pas eu beaucoup de succès. Et puis j'ai dû passer à nouveau la nuit dans la poubelle."

"Alors... est-ce que tout est encore bien ?"

"Tu pourrais dire ça."

"Bien. Alors qu'est-ce que tu as pour moi aujourd'hui?"

"Aujourd'hui, je vais vous parler de la classe RandomAccessFile ."

RandomAccessFile, etc. - 1

"Le fait est que FileInputStream et FileOutputStream représentent les fichiers comme des flux : vous ne pouvez y lire et écrire que de manière séquentielle."

"Ce n'est pas toujours très pratique. Parfois, vous devez écrire quelques lignes au milieu d'un fichier ou lire quelques pages de texte à partir de la fin d'un fichier de plusieurs mégaoctets. Il ne serait pas très efficace de lire l'ensemble du dossier pour ces tâches."

"La classe RandomAccessFile a été créée pour résoudre ce problème. Vous pouvez l'utiliser pour écrire n'importe où dans le fichier, lire à partir de celui-ci, ainsi que lire et écrire dans le fichier en même temps."

"Comme c'est intéressant !"

"Ouais. C'est en fait assez pratique."

"Mais comment lisez-vous à partir d'un emplacement arbitraire?"

"Tout est assez simple. Imaginez que vous ayez un éditeur de texte, tel que le Bloc-notes, ouvert. Il a un curseur. Lorsque vous tapez quelque chose, le texte est ajouté là où se trouve le curseur. La lecture d'un fichier est la même. La lecture commence à partir de où que se trouve le "curseur". Lors de la lecture/écriture, le curseur se déplace automatiquement."

"Tiens, ce serait mieux de te montrer un exemple :"

Lire un fichier :
// 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();

"Dans cet exemple, j'aimerais attirer votre attention sur deux choses :"

"Tout d'abord, la création de l' objet RandomAccessFile . Le deuxième argument est la lettre r. Cela signifie que le fichier est ouvert en lecture ( r - lire ). Si vous souhaitez ouvrir un fichier en lecture et en écriture, vous devez passer « rw » au constructeur, au lieu de simplement « r »."

"Deuxièmement, regardez la méthode de recherche. Vous pouvez utiliser cette méthode pour sauter dans le fichier et changer la position du curseur pour l'opération de lecture/écriture en cours. Lorsqu'un fichier est ouvert pour la première fois, le curseur est défini sur l'octet 0. Ou, plus précisément, avant le zéroième octet."

"Ai-je bien compris? Nous ouvrons le fichier et le curseur est au tout début - à la position 0. Ensuite, nous appelons seek et déplaçons le curseur au 100e octet. Et lorsque nous appelons readLine , il commence à lire à partir du centième octet . Droite?"

"Oui. Mais je veux attirer votre attention sur le fait que la méthode de recherche vous permet de sauter arbitrairement dans le fichier. Par exemple :"

Lire un fichier :
// 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();

"Dans cet exemple, nous lisons d'abord une ligne commençant au 0e octet. Ensuite, nous sautons au centième octet et lisons une ligne. Ensuite, nous sautons à nouveau au 0e octet et lisons une ligne. Cela signifie que text1 et text3 sont identiques. cordes."

"Ah. Ça rend les choses plus claires."

"Génial. Alors voici un autre exemple :"

Lire un fichier :
// 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();

"Ici, nous ouvrons le fichier en lecture et en écriture en passant « rw » ( lecture/écriture ) au constructeur."

"Ensuite, nous écrivons « C'est une chaîne » dans le fichier.

"Ensuite, nous déplaçons le curseur sur le 8ème octet (qui se trouve être le début du mot 'chaîne')"

« Alors on écrit « surprise ! » »

« Du coup, le dossier contient « C'est une surprise ! » »

"Donc, les octets ne sont pas insérés au milieu du fichier, mais remplacent-ils plutôt ceux qui s'y trouvaient?"

"Ouais."

"Et si nous déplacions le curseur à la toute fin du fichier ?"

"Ensuite, les octets seront écrits jusqu'à la fin et le fichier grossira. Ce serait donc presque comme écrire du texte dans un éditeur de texte."

"Hmm. Je pense avoir tout compris. Pourriez-vous fournir une liste complète des méthodes de la classe RandomAccessFile ?"

"Bien sur, vas y:"

Méthode Description
int read() Lit un octet et le renvoie
int read(byte b[], int off, int len) Lit un tableau d'octets
int read(byte b[]) Lit un tableau d'octets
void readFully(byte b[]) Lit un tableau d'octets et attend que de nouveaux octets soient ajoutés s'il n'y en a pas assez pour remplir le tableau
int skipBytes(int n) Ignorer n octets. En d'autres termes, cela fait avancer le curseur de n octets.
void write(int b) Écrit un octet à l'emplacement du curseur
void write(byte b[]) Écrit un tableau d'octets à l'emplacement du curseur
void write(byte b[], int off, int len) Écrit un tableau d'octets à l'emplacement du curseur
long getFilePointer() Renvoie le numéro de l'octet sur lequel pointe le curseur. Il peut aller de 0 à la longueur du fichier
void seek(long pos) Déplace le «curseur» utilisé pour la lecture/écriture à l'emplacement spécifié
long length() Renvoie la longueur du fichier
void setLength(long newLength) Définit une nouvelle longueur de fichier. Si le fichier était plus volumineux, il est tronqué ; s'il était plus petit, il développe le fichier et remplit le nouvel espace avec des zéros
void close() Ferme le dossier
boolean readBoolean() Lit un booléen à partir de la position actuelle du curseur dans le fichier
byte readByte() Lit un octet à partir de la position actuelle du curseur dans le fichier
char readChar() Lit un caractère à partir de la position actuelle du curseur dans le fichier
int readInt() Lit un entier à partir de la position actuelle du curseur dans le fichier
long readLong() Lit un long à partir de la position actuelle du curseur dans le fichier
float readFloat() Lit un flottant à partir de la position actuelle du curseur dans le fichier
double readDouble() Lit un double à partir de la position actuelle du curseur dans le fichier
String readLine() Lit une ligne du fichier et la renvoie
void writeBoolean(boolean v) Écrit un booléen dans le fichier (en partant de la position du curseur)
void writeByte(int v) t Écrit un octet dans le fichier (à partir de la position du curseur)
void writeChar(int v) Écrit un caractère dans le fichier (à partir de la position du curseur)
void writeInt(int v) Écrit un int dans le fichier (en partant de la position du curseur)
void writeLong(long v) Écrit un long dans le fichier (à partir de la position du curseur)
void writeFloat(float v) Écrit un flottant dans le fichier (à partir de la position du curseur)
void writeDouble(double v) Ecrit un double dans le fichier (en partant de la position du curseur)
void writeBytes(String s) Écrit une chaîne dans le fichier (à partir de la position du curseur)
void writeChars(String s) Écrit une chaîne dans le fichier (à partir de la position du curseur)

"Hmm. Donc, il n'y a rien de nouveau ici. Sauf peut-être les paires de méthodes seek()/getFilePointer() et length()/setLength()."

"Oui, Amigo. Tout est à peu près pareil. Mais n'est-ce pas pratique ?"

"C'est pratique. Merci, Bilaabo, pour cette leçon intéressante et pour les exemples que vous m'avez donnés."

« Content de t'aider, Amigo, mon ami !