テキストエンコーディングの問題を回避する簡単な方法はありますか?
回答:
テキストエンコーディングの問題への対処は避けられませんが、Apache Commonsには既存の解決策があります。
Reader
へInputStream
:ReaderInputStream
Writer
へOutputStream
:WriterOutputStream
必要なエンコーディングを選択するだけです。
文字列から始める場合は、次の操作も実行できます。
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
ReaderInputStream
実装では必要なメモリが少なくなります-配列内のすべてのバイトを一度に格納する必要はありません。
さて、Readerは文字を扱い、InputStreamはバイトを扱います。エンコーディングは、文字をバイトとして表現する方法を指定するため、問題を無視することはできません。問題を回避することに関しては、私の意見は次のとおりです。1つの文字セット(たとえば「UTF-8」)を選択し、それを使い続けます。
実際にそれを行う方法、などが指摘されているについては、「これらのクラスのための明白な名前がありReaderInputStreamとWriterOutputStream。」驚くべきことに、「これらはJavaライブラリに含まれていない「反対」のクラス、にも関わらず」InputStreamReaderのとのOutputStreamWriterが あります含まれています。
したがって、Apache Commons IOを含む多くの人々が独自の実装を考え出しました。ライセンスの問題によっては、プロジェクトにcommons-ioライブラリを含めたり、ソースコードの一部(ここからダウンロード可能)をコピーすることもできます。
ご覧のとおり、両方のクラスのドキュメントには、「JREでサポートされているすべての文字セットエンコーディングは正しく処理されている」と記載されています。
注意:他の回答の1つに対するコメントでは、このバグについて言及しています。ただし、これは、Apache Commons IO ReaderInputStreamクラスではなく、Apache Ant ReaderInputStreamクラス(ここ)に影響します。
また、Stringで始める場合は、次のようにCommons IOの org.apache.commons.io.IOUtilsを使用して、StringReaderの作成をスキップし、InputStreamを1つのステップで作成できます。
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
もちろん、テキストエンコーディングについて考える必要がありますが、少なくとも変換は1つのステップで行われます。
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
にを実行します。これには、レポートの2つの追加コピーのメモリへの割り当てが含まれます。レポートが大きければ、それは悪いことです。私の答えを見てください。
使用する:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
このようにする先行の変換を必要としないString
し、その後にbyte[]
レポートが大きい場合には、より多くのヒープメモリを割り当て、。StringBufferからストリームが読み込まれると、その場でバイトに変換されます。
Apache Commons IOプロジェクトのCharSequenceInputStreamを使用します。
これらのクラスのわかりやすい名前は、ReaderInputStreamおよびWriterOutputStreamです。残念ながら、これらはJavaライブラリに含まれていません。しかし、グーグルはあなたの友達です。
悪夢のようなテキストエンコーディングの問題をすべて回避できるかどうかはわかりません。
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
Cactoosを使用できます(静的メソッドではなく、オブジェクトのみ)。
逆に変換することもできます:
javaが提供するものだけを使用してストリーム内の文字列を読み取るため。
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));