133 votes

Java : Différence entre PrintStream et PrintWriter

Quelle est la différence entre PrintStream y PrintWriter ? Elles ont beaucoup de méthodes en commun, c'est pourquoi je mélange souvent ces deux classes. D'ailleurs, je pense qu'on peut les utiliser pour exactement les mêmes choses. Mais il doit y avoir une différence, sinon, il n'y aurait eu qu'une seule classe.

J'ai cherché dans les archives, mais je n'ai pas trouvé cette question.

3 votes

+1 Bonne question, je mélange aussi ces deux classes, et la doc API ne m'aide pas beaucoup non plus.

2 votes

Une autre différence est le fonctionnement de l'autoflush. Pour un écrivain, la présence d'un \n dans la sortie déclenche flush(). Mais dans un flux d'octets (PrintStream) il n'y a que des octets. autoflush fonctionne alors comme décrit dans la Javadoc, basé sur : "la notion propre à la plateforme de séparateur de ligne plutôt que le caractère de nouvelle ligne".

136voto

mdma Points 33973

Cela peut paraître désinvolte, mais PrintStream imprime dans un OutputStream y PrintWriter imprime dans un Writer . Ok, je ne pense pas que je vais obtenir des points pour avoir énoncé l'évidence. Mais il y a plus.

Alors, quelle est la différence entre un OutputStream et un Writer ? Les deux sont des flux, la différence principale étant une OutputStream est un flux d'octets tandis qu'un Writer est un flux de caractères.

Si un OutputStream traite des octets, qu'en est-il de PrintStream.print(String) ? Il convertit les caractères en octets en utilisant l'encodage par défaut de la plate-forme. L'utilisation de l'encodage par défaut est généralement une mauvaise chose car elle peut entraîner des bogues lors du passage d'une plateforme à une autre, surtout si vous générez le fichier sur une plateforme et le consommez sur une autre.

Avec un Writer vous spécifiez généralement le codage à utiliser, en évitant toute dépendance vis-à-vis de la plate-forme.

Pourquoi s'embêter à avoir un PrintStream dans le JDK, puisque l'intention première est d'écrire des caractères, et non des octets ? PrintStream est antérieure au JDK 1.1, lorsque les flux de caractères Reader/Writer ont été introduits. J'imagine que Sun aurait déprécié PrintStream ne serait-ce que pour le fait qu'il est si largement utilisé. (Après tout, vous ne voudriez pas que chaque appel à System.out pour générer un avertissement d'API obsolète ! De même, la modification du type de PrintStream a PrintWriter sur les flux de sortie standard aurait cassé les applications existantes).

3 votes

C'est ce que je pensais aussi - mais ce n'est pas vrai. Même PrintStream maintient un Writer sous le capot - si vous lui passez un OutputStream, il l'enveloppe.

4 votes

@Jon - en interne, il y a un Writer, mais il écrit dans un OutputStream, donc l'effet net est qu'un PrintStream écrit dans un OutputStream - la conversion char->byte se produit, et utilise l'encodage par défaut de la plateforme. Il n'y a pas d'exigence de conversion char->byte dans un PrintWriter, vous pouvez rester avec des caractères jusqu'au bout.

0 votes

"Le jeu de caractères par défaut est déterminé lors du démarrage de la machine virtuelle et dépend généralement de la locale et du jeu de caractères du système d'exploitation sous-jacent.", également Locale modifie le jeu de caractères par défaut sur certaines plates-formes.

60voto

BalusC Points 498232

Avec le PrintStream vous êtes bloqué par l'encodage par défaut de la plate-forme.

PrintStream stream = new PrintStream(output);

Avec le PrintWriter vous pouvez cependant passer un OutputStreamWriter avec un encodage spécifique.

PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"));

L'avantage est que vous pouvez contrôler le codage des caractères dans lequel ils doivent être écrits, de manière à ce qu'ils ne finissent pas en tant que mojibake .

22voto

Depuis le JDK 1.4, il est possible de spécifier le codage des caractères pour un PrintStream. Ainsi, les différences entre PrintStream et PrintWriter ne concernent que le comportement de vidage automatique et le fait qu'un PrintStream ne peut pas envelopper un Writer.

4voto

sblundy Points 27163

Les scripteurs comme PrintWriter sont destinés à la sortie de texte, les flux sont destinés à la sortie binaire. Les scripteurs gèrent les jeux de caractères pour vous. Les flux ne le font pas parce qu'il est supposé que vous ne voulez pas ce genre de conversion, qui gâcherait vos données binaires, et que vous utiliseriez un écrivain si vous le faisiez.

1 votes

À l'exception de PrintStream, car celui-ci prend un encodage pour pouvoir gérer un peu plus qu'un OutputStream standard.

0 votes

Il semble étrange que System.out, dont le seul but est d'imprimer des chaînes de caractères, soit en fait un PrintStream.

0 votes

"Les auteurs gèrent les jeux de caractères pour vous" -- seulement les auteurs qui s'occupent de la conversion des caractères en octets. Tous les rédacteurs ne le font pas.

2voto

Simon Groenewolt Points 7046

Vous pouvez écrire des octets bruts dans un flux et non dans un rédacteur. Le site PrintWriter La javadoc liste les autres différences (la plus importante étant la possibilité de définir un encodage sur un flux afin de pouvoir interpréter les octets bruts, je dirais).

0 votes

Avec PrintStream, on peut également spécifier l'encodage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X