it-swarm-ru.tech

Как преобразовать Reader в InputStream и Writer в OutputStream?

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

85
Andrei Savu

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

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

42
Peter

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

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

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

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

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

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

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

39
Peter Ford

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

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

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

19
Phil Harvey

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

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

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

Он использует CharSequenceInputStream из проекта Apache Commons IO.

8
Oliv
7
Bozho

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

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

5
dfrankow

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

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

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

5
Tom Hawtin - tackline

Вы пытаетесь записать содержимое Reader в OutputStream? Если это так, вам будет проще обернуть OutputStream в OutputStreamWriter и записать chars из 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
4
Sam Barnum

Вы можете использовать Cactoos (без статических методов, только объекты):

Вы можете конвертировать и наоборот:

1
yegor256

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

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

1
romeara