Salut! La leçon d'aujourd'hui sera divisée en deux parties pour plus de commodité. Nous allons répéter certains vieux sujets que nous avons abordés précédemment, et nous allons considérer quelques nouvelles fonctionnalités :) Commençons par le premier. Vous avez déjà une classe comme
BufferedReader
plusieurs fois. J'espère que vous n'avez pas eu le temps d'oublier cette déclaration :
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Avant de poursuivre votre lecture, essayez de vous rappeler de quoi chaque composant — System.in
, InputStreamReader
, BufferedReader
— est responsable et pourquoi il est nécessaire. Vous souvenez-vous ? Sinon, pas de soucis. :) Si vous avez oublié quelque chose, relisez cette leçon , qui est dédiée aux classes de lecteurs. Nous allons rappeler brièvement ce que chacun d'eux peut faire. System.in
— il s'agit d'un flux pour recevoir des données du clavier. En principe, il suffirait à lui seul de mettre en œuvre la logique nécessaire à la lecture d'un texte. Mais, comme vous vous en souviendrez, System.in
ne peut lire que des octets, pas des caractères :
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
Si nous exécutons ce code et entrons la lettre cyrillique "Й", la sortie sera :
Й
208
153
10
Les caractères cyrilliques occupent 2 octets en mémoire et s'affichent à l'écran. Le nombre 10 est la représentation décimale d'un caractère de saut de ligne, c'est-à-dire en appuyant sur Entrée. La lecture d'octets est un tel plaisir, donc l'utilisation System.in
n'est pas très pratique. Afin de lire correctement les lettres cyrilliques (et autres), nous utilisons InputStreamReader
comme wrapper :
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);
}
}
}
On entre la même lettre "Й", mais le résultat est différent cette fois :
Й
1049
10
InputStreamReader
converti deux octets (208 et 153) en un seul nombre 1049. C'est ce que signifie lire des caractères. 1049 correspond à la lettre cyrillique "Й". Nous pouvons facilement nous convaincre que cela est vrai :
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
Sortie console :
Й
Et comme forBufferedReader
(et en général, BufferedAnythingYouWant
), les classes tamponnées sont utilisées pour optimiser les performances. Accéder à une source de données (fichier, console, ressource web) est assez coûteux en termes de performances. Par conséquent, afin de réduire le nombre d'accès, BufferedReader
lit et accumule les données dans un tampon spécial, et nous les obtenons à partir de là. En conséquence, le nombre d'accès à la source de données est réduit, peut-être de plusieurs ordres de grandeur ! Une autre des BufferedReader
caractéristiques de et son avantage par rapport à l' ordinaire , est la méthode InputStreamReader
extrêmement utile , qui lit des lignes entières de données, et non des nombres individuels. readLine()
Ceci, bien sûr, est très pratique lorsqu'il s'agit de gros textes. Voici à quoi ressemblent les lignes de lecture :
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 ("The user entered the following text:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone
Bien sûr, BufferedReader
est très flexible. Vous n'êtes pas limité à travailler avec le clavier. Par exemple, vous pouvez lire des données directement depuis le Web, simplement en transmettant l'URL requise à un lecteur :
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("https://www.oracle.com/index.html");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
Vous pouvez lire les données d'un fichier en transmettant le chemin du fichier :
public class Main {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("testFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
String str;
while ((str = reader.readLine()) != null) {
System.out.println (str);
}
reader.close();
}
}
Remplacement de System.out
Examinons maintenant une fonctionnalité intéressante que nous n'avons pas abordée auparavant. Comme vous vous en souvenez sûrement, laSystem
classe a deux champs statiques — System.in
et System.out
. Ces frères jumeaux sont des objets de flux. System.in
est un InputStream
. Et System.out
est un PrintStream
. En ce moment, nous allons parler de System.out
. Si nous sautons dans le System
code source de la classe, nous voyons ceci :
public final class System {
……………...
public final static PrintStream out = null;
…………
}
Ainsi, System.out
est simplement une variable statique ordinaire de laSystem
classe. Il n'y a rien de magique là-dedans :) La out
variable est une PrintStream
référence. Voici une question intéressante : quand System.out.println()
est exécuté, pourquoi exactement la sortie va-t-elle à la console et pas ailleurs ? Et cela peut-il être changé d'une manière ou d'une autre? Par exemple, supposons que nous voulions lire les données de la console et les écrire dans un fichier texte. Est-il possible d'implémenter cela en utilisant simplement System.out
plutôt que des classes de lecture et d'écriture supplémentaires? En effet, ça l'est :) Et on peut le faire même si la System.out
variable est marquée avec le final
modificateur ! Alors, de quoi avons-nous besoin pour que cela se produise ? Tout d'abord, nous avons besoin d'un nouvel PrintStream
objet pour remplacer l'actuel. L'objet courant, défini dans leSystem
class par défaut, ne sert pas nos objectifs : il pointe vers la console. Vous devez en créer un nouveau qui pointe vers un fichier texte - la "destination" de nos données. Deuxièmement, nous devons comprendre comment attribuer une nouvelle valeur à la System.out
variable. Vous ne pouvez pas utiliser un opérateur d'affectation simple, car la variable est marquée final
. Travaillons à rebours à partir de la fin. En l'occurrence, la System
classe contient la méthode dont nous avons besoin : setOut()
. Il prend un PrintStream
objet et le définit comme destination pour la sortie. C'est exactement ce dont nous avons besoin ! Il ne reste plus qu'à créer un PrintStream
objet. C'est aussi facile :
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Le code complet ressemblera à ceci :
public class SystemRedirectService {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
/* Save the current value of System.out in a separate variable so that later
we can switch back to console output */
PrintStream console = System.out;
// Assign a new value to System.out
System.setOut(filePrintStream);
System.out.println("This line will be written to the text file");
// Restore the old value of System.out
System.setOut(console);
System.out.println("But this line will be output to the console!");
}
}
En conséquence, la première chaîne est écrite dans le fichier texte et la seconde est affichée dans la console :) Vous pouvez copier ce code dans votre IDE et l'exécuter. Ouvrez le fichier texte et vous verrez que la chaîne y a été écrite avec succès :) Avec cela, notre leçon est terminée. Aujourd'hui, nous avons rappelé comment travailler avec les flux et les lecteurs. Nous nous sommes rappelé en quoi ils diffèrent les uns des autres et avons découvert de nouvelles fonctionnalités de System.out
, que nous avons utilisées dans presque toutes les leçons :) Jusqu'aux prochaines leçons !
Plus de lecture : |
---|
GO TO FULL VERSION