Класс 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.