1. OutputStreamclasse

Nous venons tout juste d'explorer les flux d'entrée. Il est temps de parler des flux de sortie.

La OutputStreamclasse est la classe parente de toutes les classes prenant en charge la sortie d'octets. Il s'agit d'une classe abstraite qui ne fait rien par elle-même, mais elle a des classes descendantes pour chaque occasion.

Cela semble extrêmement compliqué. Pour le dire plus simplement, cette classe fonctionne sur des octets, et non, par exemple, sur des caractères ou d'autres types de données. Et le fait qu'il soit abstrait signifie que nous ne l'utilisons généralement pas, mais plutôt l'une de ses classes descendantes. Par exemple, FileOutputStreametc.

Mais revenons à la OutputStreamclasse. Cette classe a des méthodes que toutes ses classes descendantes doivent implémenter. Voici les principaux :

Méthodes Description
void write(int b)
Écrit un octet (pas un int) dans le flux.
void write(byte[] buffer)
Écrit un tableau d'octets dans le flux
void write(byte[] buffer, off, len)
Écrit une partie d'un tableau d'octets dans le flux
void flush()
Écrit toutes les données stockées dans le tampon dans le flux
void close()
Ferme le flux

Lorsque vous créez un objet d'une classe qui hérite de InputStream, vous spécifiez généralement un objet source à InputStreampartir duquel lit les données. Lorsque vous créez un objet d'une classe qui hérite de OutputStream, vous spécifiez également généralement l'objet ou le flux cible dans lequel les données seront écrites.

Passons brièvement en revue toutes les méthodes de la OutputStreamclasse :

write(int b)méthode

Cette méthode écrit un octet (pas un int) dans le flux de sortie. La valeur transmise est convertie en un octet et les trois premiers octets de l'int sont ignorés.

write(byte[] buffer)méthode

Écrit le tableau d'octets donné dans le flux de sortie. C'est ça.

write(byte[] buffer, int offset, int length)méthode

Écrit une partie du tableau d'octets transmis dans le flux de sortie. La variable offset indique l'index du premier élément du tableau, et lengthest la longueur du sous-ensemble à écrire.

flush()méthode

La flush()méthode est utilisée pour forcer toutes les données potentiellement mises en mémoire tampon dans le flux actuel à être écrites dans le flux cible. Ceci est pertinent lors de l'utilisation de la mise en mémoire tampon et/ou de plusieurs objets de flux disposés en chaîne.

close()méthode

Écrit toutes les données non écrites dans l'objet cible. La close()méthode n'a pas besoin d'être appelée si vous utilisez un try-with-resourcesbloc.

Exemple de copie d'un fichier

Code Note
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStreampour lire à partir d'un fichier
OutputStreampour écrire dans un fichier

Tampon dans lequel nous allons lire les données
Tant qu'il y a des données dans le flux

Lire les données dans le tampon
Écrire les données du tampon dans le deuxième flux

2. Writerclasse

La Writerclasse est exactement la même que la OutputStreamclasse, mais juste une différence encore une fois : elle fonctionne avec des caractères ( char) au lieu d'octets.

Il s'agit d'une classe abstraite : vous ne pouvez pas créer d'objets de la Writerclasse. Son objectif principal est d'être une classe parente commune pour des centaines de classes descendantes et de leur donner des méthodes communes pour travailler avec des flux de caractères.

Méthodes de la Writerclasse (et de toutes ses classes descendantes) :

Méthodes Description
void write(int b)
Écrit un caractère (pas un int) dans le flux.
void write(char[] buffer)
Écrit un tableau de caractères dans le flux
void write(char[] buffer, off, len)
Écrit une partie d'un tableau de caractères dans le flux
void write(String str)
Écrit une chaîne dans le flux
void write(String str, off, len)
Écrit une partie d'une chaîne dans le flux
void flush()
Écrit toutes les données stockées dans le tampon dans le flux
void close()
Ferme le flux

Les méthodes sont très similaires aux méthodes de la OutputStreamclasse, mais elles fonctionnent avec des caractères au lieu d'octets.

Description des méthodes :

write(int b)méthode

Cette méthode écrit un seul caractère ( char— pas un int) dans le flux de sortie. La valeur transmise est convertie en a charet les deux premiers octets sont ignorés.

write(char[] buffer)méthode

Écrit le tableau de caractères donné dans le flux de sortie.

write(char[] buffer, int offset, int length)méthode

Écrit une partie du tableau de caractères transmis dans le flux de sortie. La offsetvariable indique l'index du premier élément du tableau, et lengthest la longueur du sous-ensemble à écrire.

write(String str)méthode

Écrit la chaîne donnée dans le flux de sortie.

write(String str, int offset, int length)méthode

Écrit une partie de la chaîne donnée dans le flux de sortie : la chaîne est convertie en un tableau de caractères. La offsetvariable indique l'index du premier élément du tableau, et lengthest la longueur du sous-ensemble à écrire.

flush()méthode

La flush()méthode est utilisée pour forcer toutes les données potentiellement mises en mémoire tampon dans le flux actuel à être écrites dans le flux cible. Ceci est pertinent lors de l'utilisation de la mise en mémoire tampon et/ou de plusieurs objets de flux disposés en chaîne.

close()méthode

Écrit toutes les données non écrites dans l'objet cible. La close()méthode n'a pas besoin d'être appelée si vous utilisez un try-with-resourcesbloc.

Exemple de programme qui copie un fichier texte :

Code Note
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 128Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Readerpour lire à partir d'un fichier
Writerpour écrire dans un fichier

Tampon dans lequel nous allons lire les données
Tant qu'il y a des données dans le flux

Lire les données dans un tampon
Écrire les données du tampon dans le second flux

StringWriterclasse

Il existe une autre classe intéressante qui hérite de la Writerclasse : elle s'appelle StringWriter. Il contient une chaîne mutable — un StringBufferobjet. Et chaque fois que vous "écrivez" quelque chose dans l' StringWriterobjet, le texte est simplement ajouté à son tampon interne.

Exemple:

Code Note
StringWriter writer = new StringWriter();
writer.write("Hello");
writer.write(String.valueOf(123));

String result = writer.toString();
Un flux de caractères cible ( StringWriter) est créé
Une chaîne est écrite dans le tampon à l'intérieur du StringWriter
Une chaîne est écrite dans le tampon à l'intérieur du StringWriter

Convertir le contenu d'un objet en une chaîne

Dans ce cas, la StringWriterclasse est essentiellement un wrapper sur la StringBufferclasse, mais la StringWriterclasse est un descendant de la Writerclasse stream, et elle peut être utilisée dans des chaînes d'objets stream. C'est une propriété assez utile dans la pratique.



3. PrintStreamclasse

Les classes de flux de sortie peuvent également être placées dans une chaîne avec des flux intermédiaires qui écrivent des données dans le flux cible qui leur est transmis. La vue générale de l'interaction de ces flux ressemble à ceci :

Classe PrintStreamPrintStream class

Le plus intéressant et le plus polyvalent de tous les flux de sortie intermédiaires est PrintStream. Il a des dizaines de méthodes et jusqu'à 12 constructeurs.

La PrintStreamclasse hérite de la FilterOutputStreamclasse, qui hérite de OutputStream. Cela signifie que la PrintStreamclasse a toutes les méthodes des classes parentes en plus de ses propres méthodes . Voici les plus intéressants :

Méthodes Description
void print(obj)
Convertit l'objet passé en chaîne et le sort dans le flux cible.
void println(obj)
Convertit l'objet passé en chaîne et le sort dans le flux cible. Ajoute un saut de ligne à la fin
void println()
Génère un caractère de saut de ligne dans le flux cible
PrintStream format(String format, args...)
Construit et génère une chaîne basée sur la chaîne de format et les arguments passés ; semblable à la String.format()méthode

Et où sont ces dizaines de méthodes, demandez-vous ?

Eh bien, il existe de nombreuses variantes des méthodes print()et println()avec différents paramètres. Ils peuvent être résumés dans ce tableau.

Nous ne plongerons pas dans ces méthodes, car vous les connaissez déjà bien. Pouvez-vous deviner où je veux en venir ?

Vous vous souvenez System.out.println()? Mais il peut être écrit en deux lignes :

Code Sortie console
PrintStream stream = System.out;
stream.println("Hello!");
Hello!

Notre commande préférée est un appel à la méthode sur la variable statique de la classe. Et le type de cette variable est .System.out.println()println()outSystemPrintStream

Dans de nombreux niveaux CodeGym, et dans presque toutes les tâches, vous avez appelé des méthodes de la PrintStreamclasse sans même le savoir !

Utilisation pratique

Java a cette classe intéressante appelée ByteArrayOutputStream, qui est un tableau d'octets à croissance dynamique qui hérite de OutputStream.

Un ByteArrayOutputStreamobjet et PrintStreamun objet peuvent être chaînés comme ceci :

Code Description
ByteArrayOutputStream baos = new ByteArrayOutputStream();

try(PrintStream stream = new PrintStream(baos))
{
   stream.println("Hello");
   stream.println(123);
}

String result = baos.toString();

System.out.println(result);
Créez un tampon d'écriture en mémoire

Enveloppez le tampon dans un PrintStreamobjet

Écrivez des données dans la console



Convertissez le tableau en chaîne !

Sortie console :
Hello!
123