Java InputStream to String – 将Java InputStream转为字符串

最后修改: 2014年 1月 7日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll look at how to convert an InputStream to a String.

在本教程中,我们将研究如何将InputStream转换为字符串。

We’ll start by using plain Java, including Java8/9 solutions, and then look into using the Guava and Apache Commons IO libraries as well.

我们将从使用普通的Java开始,包括Java8/9的解决方案,然后研究使用GuavaApache Commons IO库,以及。

This article is part of the “Java – Back to Basic” series here on Baeldung.

这篇文章是Baeldung网站上“Java–回到基础 “系列的一部分。

2. Converting With Java – StringBuilder

2.用Java进行转换–StringBuilder

Let’s look at a simple, lower-level approach using plain Java, an InputStream and a simple StringBuilder:

让我们看看一个简单的、低级别的方法,使用普通的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);
}

3. Converting With Java 8 – BufferedReader

3.用Java 8进行转换 – BufferedReader</em

Java 8 brings a new lines() method to the BufferedReader. Let’s see how we can make use of it to convert an InputStream to a String:

Java 8给BufferedReader带来了一个新的lines()方法。让我们看看如何利用它来将InputStream转换为String:

@Test
public void givenUsingJava8_whenConvertingAnInputStreamToAString_thenCorrect() {
    String originalString = randomAlphabetic(DEFAULT_SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = new BufferedReader(
      new InputStreamReader(inputStream, StandardCharsets.UTF_8))
        .lines()
        .collect(Collectors.joining("\n"));

    assertThat(text, equalTo(originalString));
}

It’s important to mention that lines() uses the readLine() method under the hood. readLine() assumes that a line is terminated by any one of a line feed (“\n”), a carriage return (“\r”), or a carriage return followed immediately by a linefeed. In other words, it supports all the common End Of Line styles: Unix, Windows, and even old Mac OS.

值得一提的是,lines()在引擎盖下使用了readLine()方法。readLine()假定一个行是由换行(”\n”)、回车(”\r”)或回车后立即换行中的任何一个来结束的。换句话说,它支持所有常见的End Of Line样式。Unix、Windows,甚至是老式的Mac OS。

On the other hand, when we use Collectors.joining(), we need to explicitly decide which type of EOL we want to use for the created String.

另一方面,当我们使用Collectors.join()时,我们需要明确决定我们要为创建的String使用哪种类型的EOL。

We could also use the Collectors.joining(System.lineSeparator()), in which case the output depends on the system settings.

我们也可以使用Collectors.join(System.lineSeparator()),在这种情况下,输出取决于系统设置。

4. Converting With Java 9 – InputStream.readAllBytes()

4.用Java 9进行转换 – InputStream.readAllBytes()

If we’re on Java 9 or above, we can utilize a new readAllBytes method added to the InputStream:

如果我们在Java 9或以上版本,我们可以利用一个新的readAllBytes方法添加到InputStream:

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

    String text = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
    
    assertThat(text, equalTo(originalString));
}

We need to be aware that this simple code is intended for simple cases where it’s convenient to read all bytes into a byte array. We shouldn’t use it for reading input streams with large amounts of data.

我们需要注意的是,这段简单的代码是为那些方便将所有字节读入字节数组的简单情况准备的。我们不应该用它来读取有大量数据的输入流。

5. Converting With Java and a Scanner

5.用Java和扫描器进行转换

Next, let’s look at a plain Java example using a standard text 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));
}

Note that the InputStream is going to be closed by the closing of the Scanner.

注意,InputStream将被关闭的Scanner

It’s also worth clarifying what useDelimiter(“\\A”) does. Here we passed the ‘\A’, which is a boundary marker regex that denotes the beginning of the input. Essentially, this means that the next() call reads the entire input stream.

也值得澄清一下useDelimiter(“\A”)的作用。这里我们传递了’\A’,它是一个边界标记的重组词,表示输入的开始。基本上,这意味着next()调用读取整个输入流。

The only reason this is a Java 7 example, and not a Java 5 one, is the use of the try-with-resources statement. If we turn that into a standard try-finally block, it will compile just fine with Java 5.

这是一个Java 7的例子,而不是一个Java 5的例子,唯一的原因是使用了try-with-resources语句。如果我们把它变成一个标准的try-finally块,它在Java 5中就能很好地编译。

6. Converting Using ByteArrayOutputStream

6.使用ByteArrayOutputStream进行转换

Finally, let’s look at another plain Java example, this time using the ByteArrayOutputStream class:

最后,让我们看看另一个普通的Java例子,这次是使用ByteArrayOutputStream类。

@Test
public 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));
}

In this example, the InputStream is converted to a ByteArrayOutputStream by reading and writing byte blocks. Then the OutputStream is transformed to a byte array, which is used to create a String.

在这个例子中,InputStream通过读写字节块被转换为ByteArrayOutputStream。然后,OutputStream被转换为一个字节数组,用来创建一个String.

7. Converting With java.nio

7.用java.nio进行转换

Another solution is to copy the content of the InputStream to a file, and then convert it to a String:

另一个解决方案是InputStream的内容复制到一个文件,然后将其转换为字符串:

@Test
public 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));
}

Here we’re using the java.nio.file.Files class to create a temporary file, as well as to copy the content of the InputStream to the file. Then the same class is used to convert the file content to a String with the readAllBytes() method.

这里我们使用java.nio.file.Files类来创建一个临时文件,以及将InputStream的内容复制到该文件。然后用同一个类用readAllBytes()方法将文件内容转换成String

8. Converting With Guava

8.用番石榴进行转换

Let’s start with a Guava example leveraging the ByteSource functionality:

让我们从一个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));
}

Let’s go over the steps:

让我们来看看这些步骤。

  • first – we wrap our InputStream into a ByteSource, and as far as we’re aware, this is the easiest way to do so.
  • then – we view our ByteSource as a CharSource with a UTF8 charset.
  • finally – we use the CharSource to read it as a String.

A simpler way of doing the conversion is with Guava, but the stream needs to be explicitly closed; luckily, we can simply use the try-with-resources syntax to take care of that:

一种更简单的转换方式是使用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 (Reader reader = new InputStreamReader(inputStream)) {
        text = CharStreams.toString(reader);
    }
 
    assertThat(text, equalTo(originalString));
}

9. Converting With Apache Commons IO

9.使用Apache Commons IO进行转换

Now let’s look at how to do this with the Commons IO library.

现在我们来看看如何用Commons IO库来做这件事。

An important caveat here is that, as opposed to Guava, neither of these examples will close the InputStream:

这里要注意的是,与Guava不同的是,这些例子都不会关闭InputStream:

@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));
}

We can also use a StringWriter to do the conversion:

我们也可以使用一个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));
}

10. Conclusion

10.结论

In this article, we learned how to convert an InputStream to a String. We started by using plain Java, and then explored how to use the Guava and Apache Commons IO libraries.

在这篇文章中,我们学习了如何将InputStream转换为一个字符串。我们首先使用了普通的Java,然后探讨了如何使用GuavaApache Commons IO库。

The implementation of all of these examples and code snippets is available over on GitHub.

所有这些示例和代码片断的实现都可以在GitHub上获得over on GitHub