Java: Unterschied zwischen PrintStream und PrintWriter

125

Was ist der Unterschied zwischen PrintStreamund PrintWriter? Sie haben viele Methoden gemeinsam, weshalb ich diese beiden Klassen oft verwechsle. Darüber hinaus denke ich, dass wir sie für genau die gleichen Dinge verwenden können. Aber es muss einen Unterschied geben, sonst hätte es nur eine Klasse gegeben.

Ich habe die Archive durchsucht, konnte diese Frage jedoch nicht finden.

Martijn Courteaux
quelle
1
+1 Gute Frage, ich vermische auch diese beiden Klassen, und das API-Dokument hilft auch nicht viel.
Hilfsmethode
Ein weiterer Unterschied ist die Funktionsweise von Autoflush. Für einen Schreiber löst das Vorhandensein eines \ n-Zeichens in der Ausgabe Flush () aus. In einem Byte-Stream (PrintStream) gibt es jedoch nur Bytes. Autoflush funktioniert dann wie in Javadoc beschrieben, basierend auf: "Plattform-eigener Vorstellung von Zeilentrennzeichen anstelle des Zeilenumbruchs".
Minuten

Antworten:

129

Dies mag flippig klingen, wird jedoch PrintStreamauf a OutputStreamund auf a PrintWritergedruckt Writer. Ok, ich bezweifle, dass ich Punkte bekomme, um das Offensichtliche zu sagen. Aber es gibt noch mehr.

Also, was ist der Unterschied zwischen einem OutputStreamund einem Writer? Beide sind Streams, wobei der Hauptunterschied darin besteht, dass a OutputStreamein Stream von Bytes ist, während a Writerein Stream von Zeichen ist.

Wenn sich ein OutputStreammit Bytes befasst, was ist dann PrintStream.print(String)? Es konvertiert Zeichen in Bytes unter Verwendung der Standardplattformcodierung. Die Verwendung der Standardcodierung ist im Allgemeinen eine schlechte Sache, da sie beim Wechsel von einer Plattform auf eine andere zu Fehlern führen kann, insbesondere wenn Sie die Datei auf einer Plattform generieren und auf einer anderen verbrauchen.

Mit a geben WriterSie normalerweise die zu verwendende Codierung an, um Plattformabhängigkeiten zu vermeiden.

Warum sollte man sich die Mühe machen, ein PrintStreamim JDK zu haben, da die Hauptabsicht darin besteht, Zeichen und keine Bytes zu schreiben? PrintStreamälter als JDK 1.1, als Reader / Writer-Zeichenströme eingeführt wurden. Ich stelle mir vor, Sun wäre veraltet, PrintStreamwenn es nur so weit verbreitet gewesen wäre. (Schließlich möchten Sie nicht, dass jeder Aufruf System.outeine veraltete API-Warnung generiert! Außerdem hätte das Ändern des Typs von PrintStreamauf PrintWriterin den Standardausgabestreams vorhandene Anwendungen beschädigt.)

mdma
quelle
3
Das habe ich auch gedacht - aber es ist nicht wahr. Sogar PrintStream behält einen Writer unter der Haube - wenn Sie ihm einen OutputStream übergeben, wird er umbrochen.
Jon Skeet
3
@Jon - intern gibt es einen Writer, der jedoch in einen OutputStream schreibt. Der Nettoeffekt besteht also darin, dass ein PrintStream in einen OutputStream schreibt - Zeichen-zu-Byte-Konvertierung erfolgt und die Standardplattformcodierung verwendet. Es gibt keine solche Anforderung für die Zeichen-> Bytekonvertierung in einem PrintWriter. Sie können den ganzen Weg bei Zeichen bleiben.
Mdma
"Der Standardzeichensatz wird beim Start der virtuellen Maschine festgelegt und hängt normalerweise vom Gebietsschema und Zeichensatz des zugrunde liegenden Betriebssystems ab." Außerdem ändert das Gebietsschema den Standardzeichensatz auf einigen Plattformen.
Pindatjuh
7
Seit Java 1.5 PrintStreamwurde nicht auf die Verwendung der Plattform-Standardcodierung beschränkt. Es gibt Konstruktoren, die einen Zeichensatznamen akzeptieren. Daher besteht der Unterschied zwischen PrintStreamund darin, PrintWriterdass a PrintWriterkeine Rohbytes schreiben kann und die beiden Klassen unterschiedliche Arten von Zielen umschließen.
Ted Hopp
1
Es könnte sich lohnen Sie auch einen signifikanten Unterschied in ihrem Verhalten zu notieren, während sie effektiv eine Schnittstelle teilen PrintStreams‘ print()Methoden sind Funktionen , die Bequemlichkeit Anruf write(), als solche Autoflushing auslösen , wenn aktiviert. PrintWriterAuf der anderen Seite wird nach einem Anruf bei nicht automatisch gespült print(). Ich habe heute einige Java-Anfänger demonstriert, und dies hat einige Schüler herausgeholt, die mit der Notwendigkeit des manuellen Spülens nicht vertraut waren. Ansonsten ist deine Antwort großartig.
Robadob
61

Mit dem PrintStreambleiben Sie bei der Standardcodierung der Plattform.

PrintStream stream = new PrintStream(output);

Mit dem können PrintWriterSie jedoch eine OutputStreamWritermit einer bestimmten Codierung übergeben.

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

Der Vorteil ist, dass Sie die Zeichensteuerung steuern können, in die die Zeichen geschrieben werden sollen, damit sie nicht als Mojibake enden .

BalusC
quelle
12
Seit 1.4 gibt es einen neuen Konstruktor für PrintStream, der die Codierung übernimmtPrintStream(OutputStream out, boolean autoFlush, String encoding)
Artbristol
19

Seit JDK 1.4 ist es möglich, die Zeichenkodierung für einen PrintStream anzugeben. Daher bestehen die Unterschiede zwischen PrintStream und PrintWriter nur im automatischen Spülverhalten und darin, dass ein PrintStream einen Writer nicht umschließen kann.

Renan Mozone
quelle
3

Writer wie PrintWriter dienen zur Textausgabe, Streams zur Binärausgabe. Die Autoren kümmern sich um Zeichensätze. Streams tun dies nicht, weil davon ausgegangen wird, dass Sie diese Art der Konvertierung nicht möchten, die Ihre Binärdaten durcheinander bringen würde, und in diesem Fall einen Writer verwenden würden.

sblundy
quelle
1
Mit Ausnahme von PrintStream, da dieser eine Codierung verwendet, damit er etwas mehr als einen Standard-OutputStream verarbeiten kann.
Simon Groenewolt
Klingt seltsam, dass System.out, dessen einziges Ziel das Drucken von Zeichenfolgen ist, tatsächlich ein PrintStream ist.
Minuten
"Die Autoren erledigen Zeichensätze für Sie" - nur die Autoren, die sich mit der Konvertierung von Zeichen in Bytes befassen. Nicht alle Autoren tun dies.
Aivar
2

Sie können Rohbytes in einen Stream und nicht in einen Writer schreiben. Das PrintWriter-Javadoc listet die anderen Unterschiede auf (vor allem, wenn Sie eine Codierung für einen Stream festlegen können, damit die von mir angegebenen Rohbytes interpretiert werden können).

Simon Groenewolt
quelle
Mit PrintStream kann man auch die Codierung festlegen
Aivar
1

aus Core Java von Horstmann

Java-Veteranen fragen sich möglicherweise, was mit der PrintStream-Klasse und mit System.out passiert ist. In Java 1.0 hat die PrintStream-Klasse einfach alle Unicode-Zeichen in ASCII-Zeichen abgeschnitten, indem das oberste Byte gelöscht wurde. (Zu dieser Zeit war Unicode noch eine 16-Bit-Codierung.) Dies war eindeutig kein sauberer oder portabler Ansatz und wurde mit der Einführung von Lesern und Schreibern in Java 1.1 behoben. Aus Gründen der Kompatibilität mit vorhandenem Code sind System.in, System.out und System.err weiterhin Eingabe- / Ausgabestreams, keine Leser und Schreiber. Jetzt konvertiert die PrintStream-Klasse Unicode-Zeichen intern in die Standard-Host-Codierung, genau wie der PrintWriter. Objekte vom Typ PrintStream verhalten sich genau wie Druckschreiber, wenn Sie die Druck- und Druckmethoden verwenden.

Nichijou
quelle
-3

Printwriter ist eine Erweiterung von Printstream.

IE printstream für einen bestimmten Zweck.

Spoo
quelle