Есть ли простой способ избежать проблем с кодировкой текста?
87
Вы действительно не можете избежать проблем с кодировкой текста, но в Apache Commons есть существующие решения:
Reader
кому InputStream
:ReaderInputStream
Writer
кому OutputStream
:WriterOutputStream
Вам просто нужно выбрать кодировку по вашему выбору.
Если вы начинаете со String, вы также можете сделать следующее:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
источник
ReaderInputStream
реализация потребует меньше памяти - не должно быть необходимости хранить все байты в массиве сразу.Итак, Reader имеет дело с символами, а InputStream - с байтами. Кодировка определяет, как вы хотите представлять свои символы в байтах, поэтому вы не можете игнорировать проблему. Что касается избежания проблем, мое мнение таково: выберите одну кодировку (например, "UTF-8") и придерживайтесь ее.
Что касается того, как это сделать на самом деле, как уже указывалось, « очевидными именами для этих классов являются ReaderInputStream и WriterOutputStream . » Удивительно, но « они не включены в библиотеку Java », хотя «противоположные» классы, InputStreamReader и OutputStreamWriter, являются включены.
Итак, многие люди придумали свои собственные реализации, включая Apache Commons IO . В зависимости от проблем с лицензированием вы, вероятно, сможете включить библиотеку commons-io в свой проект или даже скопировать часть исходного кода (который можно загрузить здесь ).
Как видите, в документации обоих классов указано, что «все кодировки кодировки, поддерживаемые JRE, обрабатываются правильно».
NB В комментарии к одному из других ответов здесь упоминается эта ошибка . Но это влияет на класс Apache Ant ReaderInputStream ( здесь ), а не на класс Apache Commons IO ReaderInputStream.
источник
Также обратите внимание, что если вы начинаете со String, вы можете пропустить создание StringReader и создать InputStream за один шаг, используя org.apache.commons.io.IOUtils из Commons IO следующим образом:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
Конечно, вам все равно нужно подумать о кодировке текста, но, по крайней мере, преобразование происходит за один шаг.
источник
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
, который включает размещение двух дополнительных копий отчета в памяти. Если отчет большой - плохой. Смотрите мой ответ.Использование:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
Этот способ не требует предварительного преобразования в,
String
а затем вbyte[]
, который выделяет намного больше памяти кучи, если отчет большой. Он преобразуется в байты на лету, когда поток читается, прямо из StringBuffer.Он использует CharSequenceInputStream из проекта ввода-вывода Apache Commons.
источник
commons-io 2.0 имеет
WriterOutputStream
источник
Очевидные имена для этих классов - ReaderInputStream и WriterOutputStream. К сожалению, они не включены в библиотеку Java. Однако Google - ваш друг.
Я не уверен, что он решит все проблемы с кодировкой текста, которые просто кошмарны.
Есть RFE, но закрытый, исправлять не буду.
источник
Вы не можете избежать проблем с кодировкой текста, но Apache commons-io имеет
Обратите внимание, что это библиотеки, упомянутые в ответе Питера на koders.com, просто ссылки на библиотеку, а не на исходный код.
источник
Вы пытаетесь записать содержимое a
Reader
вOutputStream
? Если это так, вам будет легче обернутьOutputStream
вOutputStreamWriter
и записатьchar
s из в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.
источник
Вы можете использовать Cactoos (без статических методов, только объекты):
new InputStreamOf(reader)
new OutputStreamTo(writer)
Вы можете преобразовать и наоборот:
new ReaderOf(inputStream)
new WriterTo(outputStream)
источник
Для чтения строки в потоке, используя только то, что предоставляет java.
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));
источник