Как конвертировать Reader в InputStream и Writer в OutputStream?

Есть ли простой способ избежать проблем с текстовым кодированием?

Ответ 1

Вы не можете избежать проблем с текстовым кодированием, но существуют существующие решения:

Вам просто нужно выбрать кодировку по вашему выбору.

Ответ 2

Если вы начинаете со String, вы также можете сделать следующее:

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

Ответ 3

Ну, читатель имеет дело с символами, а InputStream - с байтами. Кодировка определяет, как вы хотите представлять свои символы в виде байтов, поэтому вы не можете игнорировать проблему. Что касается того, чтобы избежать проблем, я считаю: выберите одну кодировку (например, "UTF-8" ) и придерживайтесь ее.

Относительно того, как на самом деле это делать, как было указано, "очевидные имена для этих классов: ReaderInputStream и WriterOutputStream." Удивительно, но "они не включены в библиотеку Java", даже если "противоположные" классы, InputStreamReader и OutputStreamWriter включены.

Итак, многие люди придумали свои собственные реализации, в том числе Apache Commons IO. В зависимости от проблем с лицензированием вы, вероятно, сможете включить библиотеку commons-io в свой проект или даже скопировать часть исходного кода (который можно загрузить здесь).

Как вы можете видеть, документация обоих классов гласит, что "все кодировки кодировки, поддерживаемые JRE, обрабатываются правильно".

N.B. Комментарий к одному из других ответов здесь упоминает эту ошибку. Но это влияет на класс ReaderIputStream Apache Ant (здесь), а не Apache Commons IO Класс ReaderInputStream.

Ответ 4

Также обратите внимание, что если вы начинаете с String, вы можете пропустить создание StringReader и создать InputStream за один шаг, используя org.apache.commons.io.IOUtils из Commons IO так:

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

Конечно, вам все равно нужно подумать о кодировке текста, но, по крайней мере, преобразование происходит за один шаг.

Ответ 6

Использование:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

Этот способ не требует предварительного преобразования в String, а затем в byte[], который выделяет намного больше памяти кучи, если отчет большой. Он преобразуется в байты "на ходу", когда поток читается, прямо из StringBuffer.

Он использует CharSequenceInputStream из проекта ввода-вывода Apache Commons.

Ответ 7

Очевидными именами для этих классов являются ReaderInputStream и WriterOutputStream. К сожалению, они не включены в библиотеку Java. Однако Google является вашим другом.

Я не уверен, что он обойдет все проблемы с кодировкой текста, которые носят кошмар.

Есть RFE, но он закрыт, не будет исправлен.

Ответ 8

Вы пытаетесь записать содержимое 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

Ответ 9

Вы не можете избежать проблем с кодировкой текста, но Apache commons-io имеет

Обратите внимание, что это библиотеки, упомянутые в ответе Peter koders.com, только ссылки на библиотеку вместо исходного кода.

Ответ 10

Предупреждение при использовании WriterOutputStream - он не всегда обрабатывает двоичные данные в файле правильно/то же, что и обычный поток вывода. У меня была проблема с этим, которая заставила меня некоторое время отслеживать.

Если вы можете, я бы рекомендовал использовать выходной поток в качестве базы, и если вам нужно писать строки, используйте обертку OUtputStreamWriter вокруг потока, чтобы сделать это. Гораздо надежнее преобразовывать текст в байты, чем наоборот, что, вероятно, связано с тем, что WriterOutputStream не является частью стандартной библиотеки Java

Ответ 12

Для чтения строки в потоке, используя только то, что предоставляет Java.

InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));