Класс InputStream - это класс высокого уровня, представляющий любой
поток байтов ввода в Java. Различные подклассы дополнительно определяют
его использование, например BufferedInputStream ,
ByteArrayInputStream , SequenceInputStream и т. Д.
Само собой разумеется, что InputStream может хранить любые данные, а в
некоторых случаях они хранят содержимое String как поток байтов.
В этом руководстве мы рассмотрим, как преобразовать InputStream в строку Java .
Начнем с создания InputStream который мы будем использовать во всех
примерах. Они могут поступать из разных источников, но давайте сделаем
один из String , чтобы упростить проверку правильности вывода:
String string = "Input data, to be converted into an InputStream.";
InputStream inputStream = new ByteArrayInputStream(string.getBytes());
InputStream - это абстрактный класс, и мы использовали один из его
подклассов, ByteArrayInputStream для чтения байтов String. Теперь у
нас есть InputStream играющий роль фактического ввода, что мы можем
легко проверить, сравнив его с экземпляром string
В Java есть множество классов для работы с байтовыми потоками, и здесь нет недостатка в вариантах и подходах. Мы сосредоточимся на некоторых из них:
- InputStream в String с InputStream.readAllBytes () - лучший подход
- InputStream в String с ByteArrayOutputStream
- InputStream в String с InputStreamReader
- InputStream в String с помощью BufferedReader.lines ()
- InputStream в String с помощью Apache Commons
InputStream в String с InputStream.readAllBytes ()
Поскольку Java 9, этот процесс был упрощен много. InputStream очень
часто создается как ByteArrayInputStream перед toByteArray() для
извлечения из него байтов.
Этот процесс упрощен и заменен встроенным InputStream.readAllBytes() ,
который просто возвращает байты из InputStream - столь необходимого
служебного метода.
Класс String принимает byte в свой конструктор, из которого String
, что делает этот подход наиболее простым и читаемым для
преобразования InputStream в String :
String result = new String(inputStream.readAllBytes());
System.out.println(result);
Это приводит к:
Input data, to be converted into an InputStream.
Примечание. Если InputStream содержит больше Integer.MAX_VALUE ,
метод естественным образом вызывает OutOfMemoryError .
InputStream в String с ByteArrayOutputStream
Для версий до Java 9 самый быстрый способ преобразовать InputStream
в String - использовать ByteArrayOutputStream .
Этот подход основан на том факте, что мы можем легко создавать строки из
байтовых массивов , и на том факте, что ByteArrayOutputStream имеет
очень удобный метод toString()
Этот процесс практически противоположен тому, что мы делали в начале -
построению InputStream из String:
// 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() считывает следующий байт в массиве, начиная с
первого. Здесь мы сохраняем ссылку на первый байт как data этой
операции чтения, проверяем, -1 (дошел до конца потока) и переходим к
следующему байту с помощью другой операции read()
Выполнение этого кода приводит к:
Input data, to be converted into an InputStream.
InputStream в String с InputStreamReader
InputStream и OutputStream являются частью java.io , который также
включает действительно удобный InputStreamReader , изначально
предназначенный как класс для чтения InputStream s.
InputStreamReader считывает байты из потока и декодирует их в символы,
для которых вы также можете указать с помощью перечисления
StandardCharsets
// 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.
InputStream в String с 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());
Это приводит к тому же результату:
Input data, to be converted into an InputStream.
Примечание: этот подход предпочтительнее предыдущего из-за повышенной эффективности, даже если он может быть незаметен на меньших объемах данных.
InputStream в String с помощью BufferedReader.lines ()
В Java 8 класс BufferedReader lines() , который возвращает Stream
of String для каждой строки. Это делает его легким , чтобы прочитать
InputStream , используя 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.
InputStream в String с помощью Apache Commons
Наконец, давайте посмотрим, как добиться этого с помощью внешней библиотеки - Apache Commons, которая присутствует в значительном количестве проектов.
Чтобы использовать Apache Commons, нам нужно добавить его зависимость в наш собственный проект:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
И после этого мы можем использовать его класс 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.
Заключение
В этом руководстве мы рассмотрели, как преобразовать InputStream в
String в Java.
Мы рассмотрели новейший подход, прочитав все байты и построив String
напрямую, а также записав их в ByteArrayOutputStream перед
использованием Reader и BufferedReader и, наконец, завершив его
использованием IOUtils Apache Commons.