Reader を InputStream に変換し、Writer を OutputStream に変換するにはどうすればよいですか?
質問
テキストエンコーディングの問題を回避する簡単な方法はありますか?
解決
テキスト エンコードの問題への対処を避けることはできませんが、既存の解決策があります。
Reader
にInputStream
:ReaderInputStream
Writer
にOutputStream
:WriterOutputStream
必要なのは、好みのエンコーディングを選択することだけです。
他のヒント
文字列から始める場合は、次のこともできます。
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
Reader は文字を扱い、InputStream はバイトを扱います。エンコーディングは文字をバイトとして表現する方法を指定するため、この問題を無視することはできません。問題の回避に関して、私の意見は次のとおりです。文字セットを 1 つ選択します (例:"UTF-8") そのまま使用してください。
実際にどうするかということについては、ご指摘のとおりです。」これらのクラスのわかりやすい名前は次のとおりです。 ReaderInputStream そして ライター出力ストリーム.「驚いたことに」これらは Java ライブラリには含まれていません「たとえ「反対の」クラスであっても、 入力ストリームリーダー そして 出力ストリームライター は 含まれています。
そのため、多くの人が独自の実装を考え出しました。 アパッチ コモンズIO. 。ライセンスの問題によっては、commons-io ライブラリをプロジェクトに含めたり、ソース コードの一部 (ダウンロード可能) をコピーしたりすることもできるでしょう。 ここ).
- Apache ReaderInputStream: API / ソースコードの直接リンク
- Apache WriterOutputStream: API / ソースコードの直接リンク
ご覧のとおり、両方のクラスのドキュメントには、「JRE でサポートされているすべての文字セット エンコーディングが正しく処理される」と記載されています。
注:ここで言及されている他の回答の1つに関するコメント このバグ. 。しかし、それはApacheに影響を与えます 蟻 ReaderInputStream クラス (ここ), ない アパッチ コモンズIO ReaderInputStream クラス。
また、String から始める場合は、StringReader の作成をスキップし、org.apache.commons.io.IOUtils を使用して 1 ステップで InputStream を作成できることにも注意してください。 コモンズIO そのようです:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
もちろん、テキストのエンコーディングについて考える必要がありますが、少なくとも変換は 1 ステップで行われます。
使用:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
この方法では、事前に変換する必要はありません。 String
そしてそして byte[]
, レポートが大きい場合に備えて、より多くのヒープ メモリが割り当てられます。ストリームが StringBuffer から読み取られると、その場でバイトに変換されます。
それは使用しています CharSequence入力ストリーム Apache Commons IO プロジェクトから。
これらのクラスのわかりやすい名前は、ReaderInputStream と WriterOutputStream です。残念ながら、これらは Java ライブラリには含まれていません。ただし、Google はあなたの友達です。
悪夢のようなテキストエンコーディングの問題をすべて回避できるかどうかはわかりません。
RFEというのがあって、 しかし、それは閉じられており、修正されません。
テキストエンコーディングの問題を避けることはできませんが、 Apache Commons-io もっている
これらは koders.com の Peter の回答で参照されているライブラリであり、ソース コードではなくライブラリにリンクしているだけであることに注意してください。
の内容を書こうとしていますか? Reader
に OutputStream
?そうすれば、ラッピングするのが簡単になります。 OutputStream
で OutputStreamWriter
そして、 char
からの Reader
に Writer
, 、読者を読者に変換しようとするのではなく、 InputStream
:
final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block
WriterOutputStream を使用する場合の警告 - ファイルへのバイナリ データの書き込みが常に適切に、または通常の出力ストリームと同じように処理されるわけではありません。これには問題があり、追跡するのに時間がかかりました。
可能であれば、出力ストリームをベースとして使用し、文字列を書き込む必要がある場合は、ストリームの周囲に OUtputStreamWriter ラッパーを使用することをお勧めします。テキストをバイトに変換する方が、その逆よりもはるかに信頼性が高くなります。これが、WriterOutputStream が標準 Java ライブラリの一部ではない理由と考えられます。
使用できます サボテン (静的メソッドは使用せず、オブジェクトのみ):
逆に変換することもできます。
Java が提供するものだけを使用してストリーム内の文字列を読み取る場合。
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));