Автор оригинала: David Landup.
Класс InputStream
является классом высокого уровня, представляющим любой поток входных байтов в Java. Различные подклассы дополнительно определяют его использование, такие как BufferedInputStream
, ByteArrayInputStream
, SequenceInputStream
и т.д.
Излишне говорить, что Входной поток
может хранить любые данные, и в некоторых случаях они хранят содержимое строки в виде потока байтов.
В этом уроке мы рассмотрим как преобразовать входной поток в строку Java .
Давайте начнем с создания входного потока
, который мы будем использовать во всех примерах. Они могут поступать из различных источников, но давайте сделаем один из строки , чтобы было легко проверить правильность вывода:
String string = "Input data, to be converted into an InputStream."; InputStream inputStream = new ByteArrayInputStream(string.getBytes());
InputStream
является абстрактным классом, и мы использовали один из его подклассов, ByteArrayInputStream
для чтения байтов строки. Теперь у нас есть Входной поток
, играющий роль фактического ввода, который мы можем легко проверить, сравнив с экземпляром string
.
В Java есть множество классов для работы с потоками байтов, и здесь нет недостатка в вариантах и подходах. Мы сосредоточимся на некоторых из них:
- Входной поток в строку с помощью InputStream.ReadAllBytes() – Лучший подход
- Входной поток в строку с помощью ByteArrayOutputStream
- Входной поток в строку с помощью InputStreamReader
- Входной поток в строку с помощью BufferedReader.lines()
- Входной поток в строку с помощью Apache Commons
Входной поток в строку с помощью InputStream.ReadAllBytes()
Начиная с Java 9, этот процесс был значительно упрощен |. InputStream очень часто создается как
ByteArrayInputStream , прежде чем
toByteArray() вызывается для извлечения из него байтов.
Этот процесс оптимизирован и заменен встроенным InputStream.ReadAllBytes()
метод, который просто возвращает байты из InputStream
– столь необходимый служебный метод.
Класс String
принимает массив байт
в свой конструктор, из которого формируется и возвращается Строка
, что делает этот самый простой и наиболее читаемый подход для преобразования входного потока
в Строку
:
String result = new String(inputStream.readAllBytes()); System.out.println(result);
Это приводит к:
Input data, to be converted into an InputStream.
Примечание: Если Входной поток
содержит более целого числа.MAX_VALUE
байт, метод естественным образом выдает ошибку OutOfMemoryError
.
Входной поток в строку с помощью ByteArrayOutputStream
Для версий, предшествующих Java 9, самый быстрый способ преобразования входного потока
в строку заключается в использовании ByteArrayOutputStream
.
Этот подход основан на том факте , что мы можем легко создавать строки из байтовых массивов , и на том факте, что ByteArrayOutputStream
имеет очень удобный метод toString ()
.
Этот процесс практически является обратным тому, что мы делали в начале – построением входного потока
| из строки:
// Instantiate an OutputStream that'll store the data from the InputStream ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // For each line of the InputStream, write it to the OutputStream, and move to the next for (int data = inputStream.read(); data != -1; data = inputStream.read()) { byteArrayOutputStream.write(data); } // Convert byte array into String // Optional: You can set a character set via `StandardCharsets` here String result = byteArrayOutputStream.toString(StandardCharsets.UTF_8); System.out.println(result);
Метод InputStream.read()
считывает следующий байт в массиве, начиная с первого. Здесь мы сохраняем ссылку на первый байт как данные
этой операции чтения, проверяем, является ли это -1
(достиг конца потока) и перейдите к следующему байту с помощью другой операции read ()
.
Выполнение этого кода приводит к:
Input data, to be converted into an InputStream.
Входной поток в строку с помощью InputStreamReader
Классы InputStream
и OutputStream
являются частью java.io
пакет, который также включает в себя действительно удобный InputStreamReader
класс, первоначально предназначенный как класс для чтения InputStream
s.
InputStreamReader
считывает байты из потока и декодирует их в символы, для которых вы также можете дополнительно указать с помощью перечисления Стандартные наборы символов
:
// Read the InputStream into a Reader Reader reader = new InputStreamReader(inputStream); // Instantiate a StringBuilder to save the result StringBuilder result = new StringBuilder(); // Read each byte and convert into a char, adding to the StringBuilder for (int data = reader.read(); data != -1; data = reader.read()) { result.append((char)data); } // Convert StringBuilder to String System.out.println(result.toString());
Это также приводит к:
Input data, to be converted into an InputStream.
Входной поток в строку с помощью BufferedReader
Вместо Reader
вы также можете использовать BufferedReader
./| BufferedReader хранит большее количество байтов в
буфере перед выполнением любых операций чтения/записи. Благодаря меньшему переключению контекста это более эффективный способ чтения и записи больших объемов данных, в то время как при меньших объемах разница незаметна.
В предыдущем примере мы могли бы вместо этого завернуть InputStreamReader
в BufferedReader
:
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder sb = new StringBuilder(); for (int data = reader.read(); data != -1; data = reader.read()) { sb.append((char)data); } System.out.println(sb.toString());
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Это приводит к тому же результату:
Input data, to be converted into an InputStream.
Примечание: Этот подход предпочтительнее предыдущего из-за повышенной эффективности, хотя он может быть незаметен для небольших объемов данных.
Входной поток в строку с помощью BufferedReader.lines()
В Java 8 класс BufferedReader
получил новый метод lines ()
, который возвращает Поток
из Строки
s для каждой строки. Это делает легким чтение входного потока
с помощью API потока:
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String result = reader.lines().collect(Collectors.joining(System.lineSeparator())); System.out.println(result);
Метод Collectors.joining()
может работать без указания разделителя, однако это может привести к неожиданным результатам, когда входные данные содержат новые строки. Установив разделитель в System.LineSeparator()
, мы позволяем механизму базовой системы включаться для концов строк.
Этот код приводит к:
Input data, to be converted into an InputStream.
Входной поток в строку с помощью Apache Commons
Наконец, давайте посмотрим, как этого добиться с помощью внешней библиотеки – Apache Commons, которая присутствует в значительном количестве проектов.
Чтобы использовать Apache Commons, нам придется добавить его зависимость в ваш собственный проект:
commons-io commons-io
И с этим покончено, мы можем использовать его IOUtils
класс:
String result = IOUtils.toString(inputStream); System.out.println(result);
Метод также принимает необязательное перечисление StandardCharsets
:
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
Выполнение этого кода приводит к:
Input data, to be converted into an InputStream.
Вывод
В этом уроке мы рассмотрели, как преобразовать Входной поток
в строку в Java.
Мы рассмотрели новейший подход, прочитав все байты и построив строку напрямую, а также записав их в ByteArrayOutputStream
, перед использованием Reader
и BufferedReader
и, наконец, завершив его использованием IOUtils
Apache Commons .