Ecrire une chaîne dans le flux de sortie

139

J'ai plusieurs écouteurs de sortie qui implémentent OutputStream. Il peut s'agir d'une écriture PrintStream sur stdout ou dans un fichier, ou d'écrire dans la mémoire ou toute autre destination de sortie; par conséquent, j'ai spécifié OutputStream comme argument (un) dans la méthode.

Maintenant, j'ai reçu le String. Quelle est la meilleure façon d'écrire sur des flux ici?

Dois-je simplement utiliser Writer.write (message.getBytes ())? Je peux lui donner des octets, mais si le flux de destination est un flux de caractères, sera-t-il converti automatiquement?

Dois-je utiliser des flux de pont ici à la place?

yart
la source
2
Je ne suis pas sûr, mais il semble que vous essayez de réinventer la roue ici, avez-vous regardé à travers l'API Java Base, ainsi que l'API Commons IO?
posdef

Réponses:

149

Les flux ( InputStreamet OutputStream) transfèrent des données binaires . Si vous souhaitez écrire une chaîne dans un flux, vous devez d'abord la convertir en octets, ou en d'autres termes l' encoder . Vous pouvez le faire manuellement (comme vous le suggérez) en utilisant la String.getBytes(Charset)méthode, mais vous devriez éviter la String.getBytes()méthode, car elle utilise le codage par défaut de la JVM, qui ne peut pas être prédit de manière fiable de manière portable.

La façon habituelle d'écrire des données de caractères dans un flux, cependant, consiste à envelopper le flux dans un Writer, (souvent a PrintWriter), qui effectue la conversion pour vous lorsque vous appelez sa write(String)(ou print(String)) méthode. Le wrapper correspondant pour InputStreams est un Reader .

PrintStreamest une OutputStreamimplémentation spéciale dans le sens où elle contient également des méthodes qui encodent automatiquement des chaînes (elle utilise un écrivain en interne). Mais c'est toujours un courant. Vous pouvez encapsuler votre flux en toute sécurité avec un écrivain, qu'il s'agisse d'une PrintStreamou d'une autre implémentation de flux. Il n'y a aucun risque de double encodage.

Exemple de PrintWriter avec OutputStream:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}
MForster
la source
3
Donc utiliser PrintWriterc'est comme utiliser String.getBytes(). Il utilise tout encodage aléatoire qui se trouve être la valeur par défaut de la JVM. Donc cela ne fonctionne que si vous avez de la chance.
Christoffer Hammarström
106

OutputStream écrit des octets, String fournit des caractères. Vous devez définir Charset pour encoder la chaîne en octet []:

outputStream.write(string.getBytes(Charset.forName("UTF-8")));

Changez UTF-8pour un jeu de caractères de votre choix.

Peter Knego
la source
3
Ajouter avec la ligne suivante. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Sahil Patel
32

Vous pouvez créer un enveloppement PrintStream autour de votre OutputStream, puis l'appeler simplement print (String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();
Illarion Kovalchuk
la source
2
Quel jeu de caractères PrintStream utilise-t-il pour convertir en octets?
Dean Hiller
20

De par sa conception, cela doit être fait de cette façon:

OutputStream out = ...;
try (Writer w = new OutputStreamWriter(out, "UTF-8")) {
    w.write("Hello, World!");
} // or w.close(); //close will auto-flush
Antonio
la source
3
Notez que cela w.close()se fermera outégalement.
Franklin Yu
12

Enveloppez votre OutputStream avec un PrintWriter et utilisez les méthodes d'impression sur cette classe. Ils prennent une chaîne et font le travail pour vous.

NG.
la source
9

Vous pouvez utiliser Apache Commons IO :

try (OutputStream outputStream = ...) {
    IOUtils.write("data", outputStream, "UTF-8");
}
Félix
la source
IOUtils.write(String data, OutputStream output, Charset encoding)est implémenté comme output.write(data.getBytes(Charsets.toCharset(encoding))), donc il peut si une chaîne codée ne peut pas tenir dans un tableau d'octets
Šarūnas