Java InputStream to String

1. Обзор

В этом руководстве мы рассмотрим как преобразовать InputStream в строку , используя Guava , Apache Commons IO и простой Java.

Эта статья является частью ссылки:/java-tutorial[серия «Java - назад к основному») здесь, на Baeldung.

2. Конвертация с гуавой

Давайте начнем с примера с Guava - используя функциональность ByteSource :

@Test
public void givenUsingGuava__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    ByteSource byteSource = new ByteSource() {
        @Override
        public InputStream openStream() throws IOException {
            return inputStream;
        }
    };

    String text = byteSource.asCharSource(Charsets.UTF__8).read();

    assertThat(text, equalTo(originalString));
}

Давайте пройдемся по шагам:

  • сначала - мы оборачиваем наш InputStream в ByteSource - и насколько я

знайте, это самый простой способ сделать это затем ** - мы рассматриваем наш ByteSource как CharSource с UTF8

кодировок.

  • наконец - мы используем CharSource , чтобы прочитать его как строку.

  • Простой способ сделать преобразование с помощью Guava ** , но поток должен быть явно закрыт; к счастью, мы можем просто использовать синтаксис try-with-resources, чтобы позаботиться об этом:

@Test
public void givenUsingGuavaAndJava7__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = null;
    try (final Reader reader = new InputStreamReader(inputStream)) {
        text = CharStreams.toString(reader);
    }

    assertThat(text, equalTo(originalString));
}

3. Конвертация с Apache Commons IO

Давайте теперь посмотрим, как это сделать с библиотекой Commons IO.

Важным предупреждением здесь является то, что - в отличие от Guava - ни один из этих примеров не закроет InputStream - вот почему я лично предпочитаю решение Guava.

@Test
public void givenUsingCommonsIo__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = IOUtils.toString(inputStream, StandardCharsets.UTF__8.name());
    assertThat(text, equalTo(originalString));
}

Мы также можем использовать StringWriter для преобразования:

@Test
public void givenUsingCommonsIoWithCopy__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringWriter writer = new StringWriter();
    String encoding = StandardCharsets.UTF__8.name();
    IOUtils.copy(inputStream, writer, encoding);

    assertThat(writer.toString(), equalTo(originalString));
}

4. Преобразование с помощью Java - InputStream

Давайте теперь посмотрим на низкоуровневый подход с использованием простой Java - InputStream и простого StringBuilder :

@Test
public void givenUsingJava5__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(DEFAULT__SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringBuilder textBuilder = new StringBuilder();
    try (Reader reader = new BufferedReader(new InputStreamReader
      (inputStream, Charset.forName(StandardCharsets.UTF__8.name())))) {
        int c = 0;
        while ((c = reader.read()) != -1) {
            textBuilder.append((char) c);
        }
    }
    assertEquals(textBuilder.toString(), originalString);
}

5. Преобразование с помощью Java и Scanner

Далее - давайте посмотрим на простой пример Java - используя стандартный текст Scanner :

@Test
public void givenUsingJava7__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = null;
    try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF__8.name())) {
        text = scanner.useDelimiter("\\A").next();
    }

    assertThat(text, equalTo(originalString));
}

Обратите внимание, что InputStream будет закрыто закрытием Scanner .

Единственная причина, по которой это пример Java 7, а не Java 5, это использование оператора try-with-resources - превращение его в стандартный блок try-finally будет прекрасно компилироваться с Java 5 .

6. Преобразование с использованием ByteArrayOutputStream

Наконец, давайте посмотрим на другой простой пример Java, на этот раз используя класс ByteArrayOutputStream :

@Test
public final void givenUsingPlainJava__whenConvertingAnInputStreamToString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int nRead;
    byte[]data = new byte[1024];
    while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }

    buffer.flush();
    byte[]byteArray = buffer.toByteArray();

    String text = new String(byteArray, StandardCharsets.UTF__8);
    assertThat(text, equalTo(originalString));
}

В этом примере сначала InputStream преобразуется в ByteArrayOutputStream путем чтения и записи байтовых блоков, затем OutputStream преобразуется в байтовый массив, который используется для создания String .

7. Преобразование с помощью java.nio

Другое решение - скопировать содержимое InputStream в файл, а затем преобразовать его в String:

@Test
public final void givenUsingTempFile__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(DEFAULT__SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    Path tempFile = Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp");
    Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE__EXISTING);
    String result = new String(Files.readAllBytes(tempFile));

    assertThat(result, equalTo(originalString));
}

Здесь мы используем класс java.nio.file.Files для создания временного файла, а также для копирования содержимого InputStream в файл.

Затем тот же класс используется для преобразования содержимого файла в String с помощью метода readAllBytes () .

8. Заключение

После компиляции наилучшего способа сделать простое преобразование - InputStream в String - в правильном и удобочитаемом виде - и после просмотра стольких совершенно разных ответов и решений - я думаю, что нужна четкая и краткая лучшая практика для этого .

Реализация всех этих примеров и фрагментов кода может быть найдена на GitHub - это проект на основе Maven, так что должно быть легко импортировать и запускать как есть.