Java:PrintStreamとPrintWriterの違い


125

違いは何であるPrintStreamとはPrintWriter?これら2つのクラスをよく混同するため、共通のメソッドがたくさんあります。また、まったく同じものに使えると思います。しかし、違いがなければなりません。そうでなければ、1つのクラスしかなかっただろう。

アーカイブを検索しましたが、この質問は見つかりませんでした。


1
+1良い質問です。これら2つのクラスも混同しています。APIドキュメントもあまり役に立ちません。
ヘルパーメソッド2010年

もう1つの違いは、自動フラッシュのしくみです。ライターの場合、出力に\ n文字があると、flush()がトリガーされます。しかし、バイトストリーム(PrintStream)にはバイトしかありません。その後、autoflushは、Javadocで説明されているように、「改行文字ではなくプラットフォーム独自の行区切り文字の概念」に基づいて機能します。
2014年

回答:


129

これは軽快に聞こえるかもしれませんが、にPrintStream印刷され、OutputStreamPrintWriter印刷されますWriter。わかりました、私が明白を述べるために私がポイントを得ることを疑います。しかし、それだけではありません。

では、an OutputStreamとaの違いは何Writerですか?どちらもストリームです。主な違いは、a OutputStreamがバイトのストリームであるのに対し、a Writerは文字のストリームです。

OutputStreamバイトを扱う場合はどうPrintStream.print(String)ですか?デフォルトのプラットフォームエンコーディングを使用して文字をバイトに変換します。特に1つのプラットフォームでファイルを生成し、別のプラットフォームでそれを使用している場合は、デフォルトのエンコーディングを使用すると、プラットフォーム間を移動するときにバグが発生する可能性があるため、一般に悪いことです。

では、Writer通常、使用するエンコーディングを指定して、プラットフォームの依存関係を回避します。

PrintStream主な目的はバイトではなく文字を書き込むことなので、JDKにaが含まれているのはなぜですか。PrintStreamは、Reader / Writer文字ストリームが導入されたJDK 1.1より前のバージョンです。Sun PrintStreamがあまりにも広く使われているという事実さえあれば、Sunは非推奨になると思います。(結局のところ、呼び出しごとにSystem.out非推奨のAPI警告を生成する必要はありません!また、標準出力ストリームでタイプをからPrintStreamに変更すると、PrintWriter既存のアプリケーションが破損します。)


3
これも私が考えたことですが、そうではありません。PrintStreamでもWriterを内部で管理します。OutputStreamを渡した場合、それはラップされます。
Jon Skeet、

3
@Jon-内部にはWriterがありますが、それはOutputStreamに書き込みます。その結果、PrintStreamがOutputStreamに書き込みます-charからバイトへの変換が行われ、デフォルトのプラットフォームエンコーディングが使用されます。PrintWriterのchar-> byte変換には、そのような要件はありません。文字をそのまま使用できます。
mdma

「デフォルトの文字セットは仮想マシンの起動時に決定され、通常、基盤となるオペレーティングシステムのロケールと文字セットに依存します。」また、一部のプラットフォームでは、ロケールによってデフォルトの文字セットが変更されます。
Pindatjuh

7
Java 1.5以降PrintStream、プラットフォームのデフォルトのエンコーディングの使用に限定されていません。文字セット名を受け入れるコンストラクタがあります。したがって、との違いはPrintStreamPrintWriterPrintWriter生のバイトを書き込めず、2つのクラスは異なるタイプの宛先をラップすることです。
テッドホップ2013年

1
それらの振る舞いに大きな違いがあることにも注目する価値があるかもしれませんが、インターフェースPrintStreamprint()メソッドを効果的に共有する一方で、有効にwrite()なっていると自動フラッシュをトリガーするので、それらを呼び出す便利な関数です。PrintWriter一方、への呼び出し後は自動フラッシュされませんprint()。私は今日、Javaの初心者をデモしてきましたが、これは手動でフラッシュする必要性に慣れていない一部の学生を引き付けていました。そうでなければあなたの答えは素晴らしいです。
ロバドブ

61

ではPrintStream、あなたはプラットフォームのデフォルトのエンコーディングに立ち往生しています。

PrintStream stream = new PrintStream(output);

ではPrintWriter、あなたはしかし渡すことができOutputStreamWriter、特定のエンコードで。

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

利点は、文字が最終的にmojibakeにならないように、文字を書き込む文字エンコードを制御できることです。


12
1.4以降、エンコーディングをPrintStream(OutputStream out, boolean autoFlush, String encoding)
取得

19

JDK 1.4以降、PrintStreamの文字エンコーディングを指定することができます。したがって、PrintStreamとPrintWriterの違いは自動フラッシュの動作のみであり、PrintStreamはWriterをラップできません。


3

PrintWriterのようなライターはテキスト出力用であり、ストリームはバイナリ出力用です。ライターが文字セットを処理します。ストリームはそうではありません。バイナリデータがめちゃくちゃになり、そうした場合はライターを使用するような変換はしたくないと想定されているからです。


1
PrintStreamを除きます。これは、エンコードを取得するため、標準のOutputStreamよりも少し多く処理できるためです。
Simon Groenewolt

文字列を印刷することを唯一の目的とするSystem.outが実際にはPrintStreamであることは奇妙に聞こえます。
2014年

「ライターは文字セットを処理します」-文字をバイトに変換するライターのみ。すべてのライターがそうするわけではありません。
Aivar 2015

2

未加工のバイトは、ライターではなくストリームに書き込むことができます。PrintWriterのjavadocリスト他の相違点(最も重要なのは、それは私が言うと思います生のバイトを解釈できるように、ストリームのエンコードを設定することが可能です)。


PrintStreamを使用すると、エンコーディングも指定できます
Aivar

1

HorstmannによるコアJavaから

Javaのベテランは、PrintStreamクラスとSystem.outに何が起こったのか疑問に思うかもしれません。Java 1.0では、PrintStreamクラスは、先頭バイトを削除することにより、すべてのUnicode文字をASCII文字に切り捨てました。(当時、Unicodeは依然として16ビットエンコーディングでした。)明らかに、これはクリーンでポータブルなアプローチではなく、Java 1.1でのリーダーとライターの導入により修正されました。既存のコードとの互換性のために、System.in、System.out、およびSystem.errは引き続き入出力ストリームであり、リーダーおよびライターではありません。しかし、PrintStreamクラスは、PrintWriterが行うのと同じ方法で、Unicode文字をデフォルトのホストエンコーディングに内部的に変換するようになりました。PrintStreamタイプのオブジェクトは、printおよびprintlnメソッドを使用する場合、印刷ライターとまったく同じように動作します。


-3

Printwriterは、printstreamの拡張機能です。

特定の目的のためのIEプリントストリーム。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.