Android inputstream to string

How to convert InputStream to String in Java

1. Introduction

In this tutorial, we are going to learn how to convert an InputStream to a String in Java using plain Java, Guava, and Apache Commons IO library. Converting operations are very common requirements in many Java applications that process external resources from the filesystem or web.

For more Java I/O related articles, check the following links:

2. InputStream to a String using ByteArrayOutputStream

Using a ByteArrayOutputStream is a plain Java approach to convert InputStream to a String.

First we read bytes from the InputStream in blocks and then write them to ByteArrayOutputStream that contains method toString() which could be used to get String with the content.

Note that we might also get byte array from the ByteArrayOutputStream and use it to create a String like in the following example:

3. Converting InputStream to a String using BufferedReader

Using BufferedReader is another way to convert an InputStream to a String in Java. This approach gives us the ability to read the stream line by line.

In this example, we used BufferedReader to read InputStream line by line using InputStreamReader . StringBuilder is used to append each line to the output String.

4. InputStream to String using Guava library

Another way to convert InputStream to a String is to use external library Guava that comes with very useful utility classes and methods to perform IO operations.

First add Guava dependency into your project, available versions can be found here: com.google.guava:guava.

Note that there is a seperate library version for JRE and Android. The Android version of Guava is optimized for use on Android.

In the following example used ByteSource functionality from the Guava library:

In this example we view the ByteSource with our InputStream as a CharSource with UTF8 charset and the use read() method to read it as a String.

Luckily there is an easies way to do the conversion using Guava’s CharStreams:

In this example, we used try-with-resources syntax to automatically close the stream but Guava gives us some other great utility class that could be used to close streams:

5. Converting InputStream to String with Apache Commons IO

Conversion from the InputStream to String can be also achieved using Apache Commons IO library. Let’s start by adding a dependency to our project. The latest version of the library can be found under the following link: commons-io:commons-io

There are two approaches when using the Apache Commons IO library:

  • we can use IOUtils.copy() method or,
  • IOUtils.toString() method.

The following example shows how to use IOUtils.copy method:

The next example presents IOUtils.toString — a method, that allows us to convert InputStream into String in one line:

Читайте также:  Тойота рав 4 андроид яндекс

Keep in mind that neither copy nor toString methods from Apache Commons IO closes the stream, so you have to do it ‘manually’.

6. Java InputStream to String using Scanner

To convert an InputStream to a String we can also use Scanner class that comes with java.util package. Scanner iterates over tokens in a stream and by separating tokens using The beginning of the input — (A) we will get the whole content of the stream.

Closing the scanner scanner.close() automatically closing the stream. We could also use try-with-resources that will close scanner implicitly:

7. Converting InputStream to String using java.nio.Files class

Another way to get the content of the InputStream and put it into a String is to use Files class that is available under the new Java NIO API:

In this solution first, we need to create a temporary file and copy there the content from the InputStream . Then, we could use Files.readAllBytes method to read the content of the file and put it into a String.

8. InputStream to String conversion using Java 9 InputStream.readAllBytes() method

Since Java 9 we can readAllByte straight from the InputStream using readAllBytes method:

9. Conclusion

In this article, we presented approaches to convert InputStream to a String in Java. You should choose the best solution that suits you and will not generate any unnecessary conflicts in your project.

All examples used in this article can be found on the GitHub repository.

Источник

Шпаргалка Java программиста 7.1 Типовые задачи: Оптимальный путь преобразования InputStream в строку

У меня есть хобби: я собираю различные решения типовых задач в Java, которые нахожу в инете, и пытаюсь выбрать наиболее оптимальное по размеру/производительности/элегантности. В первую очередь по производительности. Давайте рассмотрим такую типовую задач, которые часто встречаются в программировании на Java как «преобразование InputStream в строку» и разные варианты её решения.

Посмотрим какие ограничения есть у каждого (требования подключения определенной библиотеки/определенной версии, корректная работа с unicode и т.д.). Английскую версию этой статьи можно найти в моем ответе на stackoverflow. Тесты в моем проекте на github.

Преобразование InputStream в строку (String)

Очень часто встречающая задача, давайте рассмотрим какими способами можно это сделать (их будет 11):

Используя IOUtils.toString из библиотеки Apache Commons . Один из самых коротких однострочников.

Используя CharStreams из библиотеки guava . Тоже довольно короткий код.

Используя Scanner (JDK). Решение короткое, хитрое, с помощью чистого JDK, но это скорее хак, который вынесет мозг тем кто о таком фокусе не знает.

Используя Stream Api с помощью Java 8 . Предупреждение: Оно заменяет разные переносы строки (такие как \r\n ) на \n , иногда это может быть критично.

Используя parallel Stream Api ( Java 8 ). Предупреждение: Как и 4 решение, оно заменяет разные переносы строки (такие как \r\n ) на \n .

Используя InputStreamReader и StringBuilder из обычного JDK

Используя StringWriter и IOUtils.copy из Apache Commons

Используя ByteArrayOutputStream и inputStream.read из JDK

Используя BufferedReader из JDK . Предупреждение: Это решение заменяет разные переносы строк (такие как \n\r ) на line.separator system property (например, в Windows на «\r\n»).

Используя BufferedInputStream и ByteArrayOutputStream из JDK

Используя inputStream.read() и StringBuilder ( JDK ). Предупреждение: Это решение не работает с Unicode, например с русским текстом

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

Решения 4 , 5 и 9 преобразую разные переносы строки в одну.

Решения 11 не работает с Unicode текстом

Читайте также:  Системный язык для андроид
  • Решение 1 , 7 требует использование библиотеки Apache Commons, 2 требует библиотеку Guava, 4 и 5 требуют Java 8 и выше,
  • Замеры производительности

    Предупреждение: замеры производительности всегда сильно зависят от системы, условий замера и т.п. Я измерял на двух разных компьютерах, один Windows 8.1, Intel i7-4790 CPU 3.60GHz2, 16Gb, второй — Linux Mint 17.2, Celeron Dual-Core T3500 2.10Ghz2, 6Gb, однако не могу гарантировать что результаты являются абсолютной истиной, вы всегда можете повторить тесты (test1 и test2) на вашей системе.

    Замеры производительности для небольших строк (длина = 175), тесты можно найти на github (режим = среднее время выполнения (AverageTime), система = Linux Mint 17.2, Celeron Dual-Core T3500 2.10Ghz*2, 6Gb, чем значение ниже тем лучше, 1,343 — наилучшее):

    Замеры производительности для больших строк (длина = 50100), тесты можно найти на github (режим = среднее время выполнения (AverageTime), система = Linux Mint 17.2, Celeron Dual-Core T3500 2.10Ghz*2, 6Gb, чем значение ниже тем лучше, 200,715 — наилучшее):

    График зависимости среднего времени от длины строки, система Windows 8.1, Intel i7-4790 CPU 3.60GHz 3.60GHz, 16Gb:

    Таблица зависимости среднего времени от длины строки, система Windows 8.1, Intel i7-4790 CPU 3.60GHz 3.60GHz, 16Gb:

    Выводы

    Самым быстрым решением во всех случаях и всех системах оказался 8 тест: Используя ByteArrayOutputStream и inputStream.read из JDK

    Коротким и весьма быстрым решением будет использование IOUtils.toString из Apache Commons

    Stream Api из Java 8 показывает среднее время, а использование параллельных стримов имеет смысл только при довольно большой строки, иначе он работает очень долго (что в общем-то было ожидаемо)

  • Решение 11 лучше не использовать в принципе, так как он работает медленнее всех и не работает с Unicode,
  • Источник

    Класс InputStream

    Базовый класс InputStream представляет классы, которые получают данные из различных источников:

    • массив байтов
    • строка (String)
    • файл
    • канал (pipe): данные помещаются с одного конца и извлекаются с другого
    • последовательность различных потоков, которые можно объединить в одном потоке
    • другие источники (например, подключение к интернету)

    Для работы с указанными источниками используются подклассы базового класса InputStream:

    BufferedInputStream Буферизированный входной поток ByteArrayInputStream Позволяет использовать буфер в памяти (массив байтов) в качестве источника данных для входного потока. DataInputStream Входной поток, включающий методы для чтения стандартных типов данных Java FileInputStream Для чтения информации из файла FilterInputStream Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства. InputStream Абстрактный класс, описывающий поток ввода ObjectInputStream Входной поток для объектов StringBufferInputStream Превращает строку (String) во входной поток данных InputStream PipedInputStream Реализует понятие входного канала. PushbackInputStream Входной поток, поддерживающий однобайтовый возврат во входной поток SequenceInputStream Сливает два или более потока InputStream в единый поток

    • int available() — возвращает количество байтов ввода, доступные в данный момент для чтения
    • close() — закрывает источник ввода. Следующие попытки чтения передадут исключение IOException
    • void mark(int readlimit) — помещает метку в текущую точку входного потока, которая остаётся корректной до тех пор, пока не будет прочитано readlimint байт
    • boolean markSupported() — возвращает true, если методы mark() и reset() поддерживаются потоком
    • int read() — возвращает целочисленное представление следующего доступного байта в потоке. При достижении конца файла возвращается значение -1
    • int read(byte[] buffer) — пытается читать байты в буфер, возвращая количество прочитанных байтов. По достижении конца файла возвращает значение -1
    • int read(byte[] buffer, int byteOffset, int byteCount) — пытается читать до byteCount байт в buffer, начиная с смещения byteOffset. По достижении конца файла возвращает -1
    • reset() — сбрасывает входной указатель в ранее установленную метку
    • long skip(long byteCount) — пропускает byteCount байт ввода, возвращая количество проигнорированных байтов
    Читайте также:  Fortnite android поддерживаемые устройства samsung

    Как преобразовать InputStream в строку

    1. Using IOUtils.toString (Apache Utils):
    2. Using CharStreams (guava)
    3. Using Scanner (JDK)
      символ «\А» является символом начала текста, таким образом вызов next() вернет сразу всю строку.
    4. Using Stream Api (Java 8). Warning: This solution convert different linebreaks (like \r\n) to \n.
    5. Using parallel Stream Api (Java 8). Warning: This solution convert different linebreaks (like \r\n) to \n.
    6. Using InputStreamReader and StringBuilder (JDK)
    7. Using StringWriter and IOUtils.copy (Apache Commons)
    8. Using ByteArrayOutputStream and inputStream.read (JDK)
    9. Using BufferedReader (JDK). Warning: This solution convert different linebreaks (like \n\r) to line.separator system property (for example, in Windows to «\r\n»).
    10. Using BufferedInputStream and ByteArrayOutputStream (JDK)
    11. Using inputStream.read() and StringBuilder (JDK). Warning: This soulition has problem with Unicode, for example with Russian text (work correctly only with non-Unicode text)

    Warning:
    Solutions 4, 5 and 9 convert different linebreaks to one.
    Soulution 11 can’t work correclty with Unicode text

    BufferedInputStream

    Буферизация ввода-вывода является удобным способом оптимизации производительности, позволяя заключить в оболочку любой поток класса InputStream.

    У класса есть конструктор, где размер буфера устанавливается по умолчанию. Также можно использовать конструктор, где размер буфера устанавливается вручную. Рекомендуется использовать размеры буфера, кратные размеру страницы памяти, дисковому блоку и т.п. и может зависеть от принимающей операционной системы, объёма доступной памяти и конфигурации машины.

    ByteArrayInputStream

    Класс ByteArrayInputStream использует байтовый массив в качестве источника данных. У данного класса можно не вызывать метод close().

    DataInputStream — Форматированное чтение из памяти

    Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream.

    Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream.

    При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов.

    Класс DataInputStream позволяет читать элементарные данные из потока через интерфейс DataInput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.

    FileInputStream

    Класс FileInputStream создаёт объект класса InputStream, который можно использовать для чтения байтов из файла.

    • FileInputStream (File file) — указывается объекта типа File
    • FileInputStream (FileDescriptor fd)
    • FileInputStream (String path) — указывается полное имя файла

    При создании объект открывается для чтения. Класс переопределяет методы класса InputStream, кроме методов mark() и reset().

    Для чтения байтов входного потока из файла используется конструкция:

    PushbackInputStream

    Разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток. Класс PushbackInputStream представляет механизм «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий раз, не извлекая информации.

    У класса есть дополнительный метод unread().

    SequenceInputStream

    Класс SequenceInputStream позволяет соединять вместе несколько экземпляров класса InputStream. Конструктор принимает в качестве аргумента либо пару объектов класса InputStream, либо интерфейс Enumeration.

    Во время работы класс выполняет запросы на чтение из первого объекта класса InputStream и до конца, а затем переключается на второй. При использовании интерфейса работа продолжится по всем объектам класса InputStream. По достижении конца каждого файла, связанный с ним поток закрывается. Закрытие потока, созданного объектом класса SequenceInputStream, приводит к закрытию всех открытых потоков.

    Источник

    Оцените статью