JavaRush /Blog Java /Random-FR /Lecture au clavier - « lecteurs »

Lecture au clavier - « lecteurs »

Publié dans le groupe Random-FR
Bonjour! Au cours des cours et des devoirs, nous avons appris à afficher des données sur la console et, vice versa, à lire des données à partir du clavier. Lecture au clavier - "lecteurs" - 1Vous avez même appris à utiliser une construction complexe pour cela :
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Mais nous n’avons toujours pas répondu à une question.

Comment est-ce que ça marche ?

En fait, le plus souvent, un programme n’existe pas en soi. Il peut communiquer avec d’autres programmes, systèmes, Internet, etc. Par le mot « communiquer », nous entendons avant tout « échanger des données ». Autrement dit, recevez des données de l'extérieur et, au contraire, envoyez vos propres données quelque part. Il existe de nombreux exemples d’échange de données entre programmes, même dans la vie quotidienne. Ainsi, sur de nombreux sites, au lieu de vous inscrire, vous pouvez vous connecter via votre compte Facebook ou Twitter. Dans cette situation, deux programmes, par exemple Twitter et le site sur lequel vous essayez de vous inscrire, échangent les données nécessaires, après quoi vous voyez le résultat final - une autorisation réussie. Le terme « flux » est souvent utilisé pour décrire le processus d'échange de données en programmation . D’où vient ce nom ? « Flow » est davantage associé à une rivière ou à un ruisseau qu'à une programmation. En fait, ce n'est pas sans raison :) Un flux est, par essence, une donnée en mouvement. Autrement dit, en programmation, ce n'est pas l'eau qui « coule » le long du flux, mais les données sous forme d'octets et de caractères. À partir d’un flux de données, nous pouvons recevoir des données en partie et en faire quelque chose. Encore une fois, utilisons l’analogie de « l’eau qui coule » : vous pouvez puiser l’eau d’une rivière pour faire cuire de la soupe, éteindre un feu ou arroser des fleurs. En utilisant les flux, vous pouvez travailler avec n'importe quelle source de données : Internet, le système de fichiers de votre ordinateur ou autre chose - cela n'a pas d'importance. Les flux sont un outil universel. Ils permettent au programme de recevoir des données de n'importe où (flux entrants) et de les envoyer n'importe où (flux sortants). Leur tâche en est une : récupérer les données à un endroit et les envoyer à un autre. Les flux sont divisés en deux types :
  1. Flux entrant ( Entrée ) - utilisé pour recevoir des données
  2. Flux sortant ( Sortie ) - pour l'envoi de données.
Le flux de données entrant en Java est implémenté dans la classe InputStreamet le flux de données sortant dans la classe OutputStream. Mais il existe une autre façon de diviser les fils. Ils sont divisés non seulement en entrants et sortants, mais également en octets et caractères . Ici, le sens est clair sans explication : un flux d'octets transmet des informations sous la forme d'un ensemble d'octets, et un flux de caractères transmet des informations sous la forme d'un ensemble de caractères. Dans cette conférence, nous entrerons dans les détails des flux entrants. Et je joindrai des informations sur les liens sortants à la fin, et vous pourrez les lire vous-même :) Donc, notre code :
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Vous avez probablement pensé en lisant les conférences que cela avait l'air assez effrayant ? :) Mais ce n'est que jusqu'à ce que nous comprenions comment cette chose fonctionne. Réparons-le maintenant ! Commençons par la fin. System.inest un objet de la classe InputStreamdont nous avons parlé au début. Il s'agit d'un flux entrant et il est lié au périphérique d'entrée du système - le clavier. D’ailleurs, vous le connaissez indirectement. Après tout, vous utilisez souvent son « collègue » dans votre travail - System.out! System.out- il s'agit d'un flux de sortie de données système , il est utilisé pour la sortie vers la console de la même manière System.out.println()que vous utilisez constamment :) System.out- un flux pour envoyer des données à la console, et System.in- pour recevoir des données du clavier. C'est simple :) De plus : pour lire les données du clavier, on peut se passer de cette grosse construction et écrire simplement : System.in.read();
public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
Dans la classe InputStream(et System.in, je vous le rappelle, est un objet de la classe InputStream) il existe une méthode read()qui permet de lire des données. Un problème : il lit les bytes , pas les caractères . Essayons de lire la lettre russe « Ya » sur le clavier. Sortie de la console :
Я
208
175
10
Les lettres russes occupent 2 octets dans la mémoire de l'ordinateur (contrairement aux lettres anglaises, qui n'en occupent que 1). Dans ce cas, 3 octets ont été lus dans le flux : les deux premiers représentent notre lettre « I », et l'autre est le saut de ligne (Entrée). Par conséquent, l’option d’utiliser « nu » System.inne nous conviendra pas. Les humains (à de rares exceptions près !) ne peuvent pas lire les octets. C'est là que la prochaine classe nous vient en aide - InputStreamReader! Voyons de quel genre d'animal il s'agit.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
Nous transmettons le flux System.inau InputStreamReader. En général, si vous traduisez son nom en russe, tout semble évident - « lecteur de flux entrants ». En fait, c'est exactement à ça que ça sert ! Nous créons un objet de classe InputStreamReaderet lui transmettons un flux entrant à partir duquel il doit lire les données. Dans ce cas...
new InputStreamReader(System.in)
...nous lui disons : « vous lirez les données du flux d'entrée du système (clavier). » Mais ce n’est pas sa seule fonction ! InputStreamReadernon seulement reçoit les données du flux. Il convertit également les flux d'octets en flux de caractères . En d'autres termes, vous n'avez plus à vous soucier de traduire les données lues du langage « informatique » vers le langage « humain » - InputStreamReaderil fera tout pour vous. InputStreamReader, bien sûr, peut lire des données non seulement depuis la console, mais également depuis d'autres endroits. Par exemple, à partir du fichier :
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
Ici, nous avons créé un flux de données entrant FileInputStream(c'est l'une des variétés InputStream), y avons transmis le chemin d'accès au fichier et transmis le flux lui InputStreamReader-même. Il pourra désormais lire les données de ce fichier, si le fichier à ce chemin existe, bien sûr. Pour lire des données (peu importe d'où, depuis la console, un fichier ou n'importe où ailleurs), la classe InputStreamReaderutilise également le read(). Quelle est la différence entre System.in.read()et InputStreamReader.read()? Essayons de compter la même lettre « I » en utilisant InputStreamReader. Je vous rappelle, voici ce que je pensais System.in.read():
Я
208
175
10
Comment peut-il faire le même travail InputStreamReader?
public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
Sortie de la console :
Я
1071
10
La différence est immédiatement visible. Le dernier octet - pour les sauts de ligne - est resté inchangé (le chiffre 10), mais la lettre lue « I » a été convertie en un seul code « 1071 ». C'est une lecture par symboles ! Si du coup vous ne croyez plus que le code 1071 signifie la lettre « I », c'est facile à vérifier :)
import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       char x = 1071;
       System.out.println(x);
   }
}
Sortie de la console :

Я
Mais si InputStreamReaderc’est si bon, pourquoi en as-tu besoin de plus BufferedReader? InputStreamReaderpeut à la fois lire des données et convertir des octets en caractères - de quoi d'autre avons-nous besoin ? Pourquoi un autre lecteur ? :/ La réponse est très simple : pour une plus grande productivité et une plus grande commodité . Commençons par les performances. Lors de la lecture des données, BufferedReader utilise une zone spéciale - un tampon, où il « ajoute » les caractères lus. De ce fait, lorsque nous aurons besoin de ces caractères dans le programme, ils seront extraits du tampon, et non directement de la source de données (clavier, fichier, etc.), ce qui permet d'économiser beaucoup de ressources. Pour comprendre comment cela fonctionne, imaginez, par exemple, le travail d'un coursier dans une grande entreprise. Le coursier est assis au bureau et attend que les colis lui soient apportés pour être livrés. Chaque fois qu'il reçoit un nouveau colis, il peut immédiatement prendre la route. Mais il peut y avoir beaucoup de colis dans la journée, et il devra à chaque fois se déplacer entre le bureau et les adresses. Au lieu de cela, le coursier a placé une boîte dans le bureau où chacun pouvait déposer ses colis. Désormais, le coursier peut tranquillement prendre la boîte et se rendre aux adresses - il gagnera beaucoup de temps, car il n'aura pas à retourner au bureau à chaque fois. La boîte dans cet exemple est précisément le tampon et le bureau est la source de données. Il est beaucoup plus facile pour un coursier de sortir une lettre d'une boîte commune pour la livrer que de se rendre au bureau à chaque fois. Cela permettra également d'économiser de l'essence. C'est la même chose dans un programme : il faut beaucoup moins de ressources pour extraire des données du tampon, plutôt que d'accéder à la source de données à chaque fois. C'est pourquoi BufferedReader+ InputStreamReaderfonctionne plus rapidement que simplement InputStreamReader. Nous avons réglé les performances, mais qu'en est-il de la commodité ? Le principal avantage est qu’il BufferedReaderpeut lire les données non seulement un caractère à la fois (bien qu’il read()dispose également d’une méthode à cet effet), mais également des lignes entières ! Cela se fait en utilisant le readLine();
public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("We read this line from the keyboard:");
       System.out.println(s);
   }
}
Sortie de la console :
JavaRush is the best site to learn Java!
Мы считали с клавиатуры эту строку:
JavaRush — лучший сайт для изучения Java!
Ceci est particulièrement utile lors de la lecture d’une grande quantité de données. Une ou deux lignes de texte peuvent toujours être lues caractère par caractère. Mais compter "Guerre et Paix" une lettre à la fois sera quelque peu problématique :) Maintenant, le travail des fils de discussion est devenu beaucoup plus clair pour vous. Pour une étude plus approfondie, voici une source supplémentaire pour vous : Ici, vous pouvez en savoir plus sur les flux entrants et sortants. Revue vidéo BufferedReaderd'un de nos étudiants. Oui, oui, nos étudiants apprennent non seulement eux-mêmes, mais enregistrent également des vidéos éducatives pour les autres ! N'oubliez pas d'aimer et de vous abonner à notre chaîne :)
Il vaut mieux s’habituer à lire la documentation officielle dès le début de ses études. C’est la principale source de connaissances sur la langue, et la plupart des réponses peuvent toujours y être trouvées.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION