1. InputStreamReaderclasse

Une autre caractéristique intéressante des flux est que vous pouvez combiner plusieurs flux en chaînes . Un flux peut lire des données non seulement à partir de sa source de données interne, mais également à partir d' un autre flux .

Il s'agit d'un mécanisme très puissant en Java, qui permet de créer des scénarios complexes de lecture de données en connectant un flux à un autre. Un tel schéma ressemble à ceci:

Classe InputStreamReaderInputStreamReader class

Lorsqu'un programme lit des données à partir d'un flux de données, le flux de données lit à son tour les données à partir de sa source de données, qui est un autre flux de données ou un fichier, par exemple.

De plus, chaque flux de données non seulement lit et transmet des données, mais peut également les transformer ou effectuer diverses opérations dessus. Un bon exemple d'un tel "flux intermédiaire" est la InputStreamReaderclasse.

Nous connaissons déjà une classe appelée FileReader- c'est un Readerqui lit les données d'un fichier. Et d'où InputStreamReadertire ses données ? C'est vrai - d'un InputStream.

Lorsque vous créez un InputStreamReaderobjet, vous devez transmettre un InputStreamobjet ou l'une de ses classes descendantes. Exemple:

String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);

La InputStreamReaderclasse a toutes les méthodes que la Readerclasse a, et elles fonctionnent exactement de la même manière.

La principale différence entre la InputStreamReaderclasse et, par exemple, FileReaderest l'endroit où ils lisent les données. FileReaderlit les données d'un fichier (duh - c'est pourquoi il s'appelle FileReader), mais InputStreamReaderlit les données d'un fichier InputStream.

Lorsque vous lisez un caractère à partir d'un FileReaderobjet à l'aide de la read()méthode, il lit à son tour deux octets du fichier sur le disque et les renvoie sous la forme chars.

Lorsque vous lisez un caractère d'un InputStreamReaderobjet à l'aide de la read()méthode, il lit à son tour deux octets de l' FileInputStreamobjet qui lui est transmis, qui lit à son tour les données du fichier. Le résultat est une chaîne d'appels de read()méthodes.


2. BufferedReaderclasse

Une autre classe intéressante que vous utiliserez probablement beaucoup est BufferedReader. Il s'agit également d'un "flux intermédiaire" qui lit les données d'un autre flux.

Comme son nom l'indique, la BufferedReaderclasse est une sous-classe de Readeret permet de lire des caractères . Mais ce qui est le plus intéressant, c'est qu'il faut aussi lui passer une source de données sous la forme d'un flux à partir duquel des caractères peuvent être lus , c'est-à-dire un flux qui hérite de la Readerclasse.

À quoi ça sert? Contrairement à InputStreamReader, la BufferedReaderclasse ne convertit pas les octets en caractères : elle ne convertit rien du tout. Au lieu de cela, il met les données en mémoire tampon .

Lorsqu'un programme lit un seul caractère à partir d'un BufferedReaderobjet, l'objet lit un grand nombre de caractères à partir de son flux source en une seule fois. Et les stocke en interne.

Lorsque le caractère suivant est lu à partir de l' BufferedReaderobjet, il saisit simplement le caractère suivant de son tableau de mémoire tampon interne et le renvoie sans accéder à la source de données. Ce n'est que lorsque tous les caractères du tampon sont épuisés qu'il lit un autre grand tableau de caractères.

La BufferedReaderclasse possède également une méthode très utile — String readLine(), qui vous permet de lire en une seule fois des chaînes entières de données à partir du flux source. Vous pouvez utiliser cette méthode pour, par exemple, lire un fichier et afficher son contenu ligne par ligne à l'écran. Exemple:

Nous avons spécifiquement écrit un code compact pour illustrer à quel point cela peut être pratique. Ce code pourrait également être écrit avec un peu plus de détails.

String src = "c:\\projects\\log.txt";

try(FileReader in = new FileReader(src);
BufferedReader reader = new BufferedReader(in))
{
   while (reader.ready())
   {
      String line = reader.readLine();
      System.out.println(line);
   }
}
Créer un FileReaderobjet. La source de données est un fichier.
Créer un BufferedReaderobjet. La source de données est un FileReader.
Tant qu'il reste des données dans le lecteur
Lire une ligne
Afficher la ligne
Un point important :

Si vous enchaînez plusieurs flux, la close()méthode n'a besoin d'être appelée que sur l'un d'entre eux. Ce flux appellera la méthode sur sa source de données, et ainsi de suite, jusqu'à ce qu'il close()soit appelé sur le flux de données final.



3. Lecture depuis la console

Et un autre fait intéressant : la Scannerclasse n'est rien de plus qu'un flux d'entrée intermédiaire qui lit les données de System.in, qui est également un flux de données.

Voici deux manières de lire une ligne depuis la console :

Classe de numérisation Classes BufferedReader et BufferedWriter
InputStream stream = System.in;
Scanner console = new Scanner(stream);
String line = console.nextLine();
InputStream stream = System.in;
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader buff = new BufferedReader(reader);
String line = buff.readLine();

Notre ami n'est rien de plus qu'une variable statique de la classe. C'est un dont le nom est .System.ininSystemInputStreamin

Ainsi, presque depuis le tout début de vos études Java sur CodeGym, vous avez travaillé avec des flux de données et créé des chaînes à partir de ceux-ci. Mais maintenant, vous le ferez plus consciemment.