Un guide de la classe Java FileReader

1. Vue d'ensemble

Comme son nom l'indique, FileReader est une classe Java qui facilite la lecture du contenu d'un fichier .

Dans ce didacticiel, nous allons apprendre le concept de base d'un lecteur et comment nous pouvons utiliser la classe FileReader pour effectuer des opérations de lecture sur un flux de caractères en Java.

2. Principes de base du lecteur

Si nous examinons le code de la classe FileReader , nous remarquerons que la classe contient un code minimal pour créer un objet FileReader et aucune autre méthode.

Cela soulève des questions telles que «Qui fait le gros du travail derrière ce cours?»

Pour répondre à cette question, nous devons comprendre le concept et la hiérarchie de la classe Reader en Java.

Reader est une classe de base abstraite qui rend possible la lecture de caractères grâce à l'une de ses implémentations concrètes. Il définit les opérations de base suivantes de lecture de caractères à partir de n'importe quel support tel que la mémoire ou le système de fichiers:

  • Lire un seul caractère
  • Lire un tableau de caractères
  • Marquer et réinitialiser une position donnée dans un flux de caractères
  • Sauter la position lors de la lecture d'un flux de caractères
  • Fermer le flux d'entrée

Naturellement, toutes les implémentations de la classe Reader doivent implémenter toutes les méthodes abstraites, à savoir read () et close () . De plus, la plupart des implémentations remplacent également d'autres méthodes héritées pour offrir des fonctionnalités supplémentaires ou de meilleures performances.

2.1. Quand utiliser un FileReader

Maintenant que nous avons une certaine compréhension d'un Reader , nous sommes prêts à ramener notre attention sur la classe FileReader .

FileReader hérite de ses fonctionnalités d' InputStreamReader , qui est une implémentation de Reader conçue pour lire les octets d'un flux d'entrée sous forme de caractères.

Voyons cette hiérarchie dans les définitions de classe:

public class InputStreamReader extends Reader {} public class FileReader extends InputStreamReader {}

En général, nous pouvons utiliser un InputStreamReader pour lire des caractères à partir de n'importe quelle source d'entrée.

Cependant, lorsqu'il s'agit de lire du texte à partir d'un fichier, utiliser un InputStreamReader équivaudrait à couper une pomme avec une épée. Bien sûr, le bon outil serait un couteau, ce que FileReader promet.

Nous pouvons utiliser un FileReader lorsque nous voulons lire du texte à partir d'un fichier en utilisant le jeu de caractères par défaut du système. Pour toute autre fonctionnalité avancée, ce serait idéal pour utiliser directement la classe InputStreamReader .

3. Lire un fichier texte avec un FileReader

Passons en revue un exercice de codage de lecture de caractères à partir d'un fichier HelloWorld.txt à l'aide d'une instance FileReader .

3.1. Créer un FileReader

En tant que classe pratique, FileReader propose trois constructeurs surchargés qui peuvent être utilisés pour initialiser un lecteur capable de lire un fichier en tant que source d'entrée.

Jetons un coup d'œil à ces constructeurs:

public FileReader(String fileName) throws FileNotFoundException { super(new FileInputStream(fileName)); } public FileReader(File file) throws FileNotFoundException { super(new FileInputStream(file)); } public FileReader(FileDescriptor fd) { super(new FileInputStream(fd)); }

Dans notre cas, nous connaissons le nom de fichier du fichier d'entrée. Par conséquent, nous pouvons utiliser le premier constructeur pour initialiser un lecteur:

FileReader fileReader = new FileReader(path);

3.2. Lire un seul caractère

Ensuite, créons readAllCharactersOneByOne () , une méthode pour lire les caractères du fichier un par un:

public static String readAllCharactersOneByOne(Reader reader) throws IOException { StringBuilder content = new StringBuilder(); int nextChar; while ((nextChar = reader.read()) != -1) { content.append((char) nextChar); } return String.valueOf(content); }

Comme nous pouvons le voir dans le code ci-dessus, nous avons utilisé la méthode read () dans une boucle pour lire les caractères un par un jusqu'à ce qu'il renvoie -1 , ce qui signifie qu'il n'y a plus de caractères à lire.

Maintenant, testons notre code en validant que le texte lu dans le fichier correspond au texte attendu:

@Test public void givenFileReader_whenReadAllCharacters_thenReturnsContent() throws IOException { String expectedText = "Hello, World!"; File file = new File(FILE_PATH); try (FileReader fileReader = new FileReader(file)) { String content = FileReaderExample.readAllCharactersOneByOne(fileReader); Assert.assertEquals(expectedText, content); } }

3.3. Lecture d'un tableau de caractères

Nous pouvons même lire plusieurs caractères à la fois en utilisant la méthode héritée read (char cbuf [], int off, int len) :

public static String readMultipleCharacters(Reader reader, int length) throws IOException { char[] buffer = new char[length]; int charactersRead = reader.read(buffer, 0, length); if (charactersRead != -1) { return new String(buffer, 0, charactersRead); } else { return ""; } }

Il y a une différence subtile dans la valeur de retour de read () lorsqu'il s'agit de lire plusieurs caractères dans un tableau. La valeur de retour ici est soit le nombre de caractères lus, soit -1 si le lecteur a atteint la fin du flux d'entrée.

Ensuite, testons l'exactitude de notre code:

@Test public void givenFileReader_whenReadMultipleCharacters_thenReturnsContent() throws IOException { String expectedText = "Hello"; File file = new File(FILE_PATH); try (FileReader fileReader = new FileReader(file)) { String content = FileReaderExample.readMultipleCharacters(fileReader, 5); Assert.assertEquals(expectedText, content); } }

4. Limitations

Nous avons vu que la classe FileReader repose sur le codage de caractères système par défaut.

Ainsi, pour les situations où nous devons utiliser des valeurs personnalisées pour le jeu de caractères, la taille de la mémoire tampon ou le flux d'entrée, nous devons utiliser InputStreamReader .

De plus, nous savons tous que les cycles d'E / S sont coûteux et peuvent introduire une latence dans notre application. Il est donc dans notre meilleur intérêt de minimiser le nombre d'opérations d'E / S en enveloppant un BufferedReader autour de notre objet FileReader :

BufferedReader in = new BufferedReader(fileReader);

5. Conclusion

Dans ce didacticiel, nous avons découvert les concepts de base d'un Reader et comment FileReader simplifie les opérations de lecture sur des fichiers texte à l' aide de quelques exemples.

Comme toujours, le code source complet du didacticiel est disponible sur GitHub.