web-dev-qa-db-ja.com

リーダーをInputStreamに、ライターをOutputStreamに変換する方法は?

テキストエンコーディングの問題を回避する簡単な方法はありますか?

87
Andrei Savu

テキストエンコーディングの問題への対処を避けることはできませんが、既存のソリューションがあります。

好みのエンコーディングを選択するだけです。

43
Peter

文字列で始める場合は、次のこともできます。

new ByteArrayInputStream(inputString.getBytes("UTF-8"))
93

リーダーは文字を扱い、InputStreamはバイトを扱います。エンコードは、文字をバイトとして表現する方法を指定するため、実際に問題を無視することはできません。問題を回避するために、私の意見は次のとおりです。1つの文字セット(たとえば、「UTF-8」)を選択し、それを使用します。

実際にそれを行う方法に関して、指摘されているように、「これらのクラスの明白な名前はReaderInputStreamおよびWriterOutputStreamです。 "驚くべきことに、" これらは、 'opposite'クラス、 InputStreamReader および-でも、Java library "に含まれません。 OutputStreamWriterareが含まれています。

そのため、ApacheCommons IO など、多くの人々が独自の実装を考え出しました。ライセンスの問題に応じて、commons-ioライブラリをプロジェクトに含めるか、ソースコードの一部をコピーすることもできます(ダウンロード可能 here )。

ご覧のとおり、両方のクラスのドキュメントには、「JREでサポートされるすべての文字セットエンコーディングが正しく処理される」と記載されています。

N.B.ここでの他の回答の1つに対するコメントには、 このバグ が記載されています。ただし、ApacheAntReaderInputStreamクラス( here )、not ApacheCommons IOReaderInputStreamクラス。

41
Peter Ford

また、文字列で開始する場合は、 Commons IO のorg.Apache.commons.io.IOUtilsを使用して、StringReaderの作成をスキップし、InputStreamを1ステップで作成できます。

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

もちろん、まだテキストエンコーディングについて考える必要がありますが、少なくとも1つのステップで変換が行われます。

19
Phil Harvey

つかいます:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

この方法では、Stringからbyte[]。レポートが大きい場合に、より多くのヒープメモリを割り当てます。 StringBufferからストリームが読み取られると、すぐにバイトに変換されます。

Apache Commonsの CharSequenceInputStream を使用しますIOプロジェクト。

8
Oliv
7
Bozho

テキストエンコーディングの問題を避けることはできませんが、 Apache commons-io

これらはkoders.comのPeterの回答で参照されているライブラリであり、ソースコードの代わりにライブラリにリンクしているだけです。

5
dfrankow

これらのクラスの明白な名前はReaderInputStreamとWriterOutputStreamです。残念ながら、これらはJavaライブラリに含まれていません。ただし、googleはあなたの友達です。

悪夢のようなすべてのテキストエンコーディングの問題を回避できるかどうかはわかりません。

RFEがあります しかし、クローズされているため、修正されません。

Readerの内容をOutputStreamに書き込もうとしていますか?その場合、OutputStreamOutputStreamWriterにラップして、charからReaderWriterを書き込むのは簡単です。リーダーを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
4
Sam Barnum

Cactoos (静的メソッドなし、オブジェクトのみ)を使用できます。

他の方法でも変換できます:

1
yegor256

WriterOutputStreamを使用する場合の警告-バイナリデータのファイルへの書き込みが常に適切に処理されるとは限りません/通常の出力ストリームと同じです。これに問題があり、追跡に時間がかかりました。

可能であれば、出力ストリームをベースとして使用することをお勧めします。文字列を記述する必要がある場合は、ストリームの周りにOUtputStreamWriterラッパーを使用してそれを実行します。テキストをバイトに変換する方がはるかに信頼性が高いため、WriterOutputStreamが標準のJavaライブラリの一部ではない可能性が高い

1
romeara