1. Overview
1.概述
In this article, we’ll have a look at StreamUtils class and how we can use it.
在这篇文章中,我们将看看StreamUtils类以及我们如何使用它。
Simply put, StreamUtils is a Spring’s class that contains some utility methods for dealing with stream – InputStream and OutputStream which reside in the package java.io and not related to the Java 8’s Stream API.
简单地说,StreamUtils是Spring的一个类,它包含一些处理流的实用方法–InputStream和OutputStream,它们位于java.io包中,与Java 8的流API没有关系。
2. Maven Dependency
2.Maven的依赖性
StreamUtils class is available in the spring-core module so let’s add it to our pom.xml:
StreamUtils类在spring-core模块中可用,所以让我们把它添加到我们的pom.xml。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
You can find the latest version of the library at the Maven Central Repository.
您可以在Maven Central Repository上找到该库的最新版本。
3. Copying Streams
3.复制数据流
The StreamUtils class contains several overloaded methods named copy() as well as some other variations:
StreamUtils类包含几个名为copy()的重载方法,以及其他一些变化。
- copyRange()
- copyToByteArray()
- copyString()
We can copy streams without using any libraries. However, the code is going to be cumbersome and much harder to read and understand.
我们可以不使用任何库来复制流。但是,代码会很繁琐,而且更难阅读和理解。
Note that we’re omitting closing of streams for the sake of simplicity.
注意,为了简单起见,我们省略了流的关闭。
Let’s see how we can copy the content of an InputStream to a given OutputStream:
让我们看看如何将一个InputStream的内容复制到一个给定的OutputStream。
@Test
public void whenCopyInputStreamToOutputStream_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
String outputFileName = "src/test/resources/output.txt";
File outputFile = new File(outputFileName);
InputStream in = new FileInputStream(inputFileName);
OutputStream out = new FileOutputStream(outputFile);
StreamUtils.copy(in, out);
assertTrue(outputFile.exists());
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(inputFileContent, outputFileContent);
}
The created file contains the content of the InputStream.
创建的文件包含InputStream的内容。
Note that getStringFromInputStream() is a method that takes an InputStream and returns its content as a String. The implementation of the method is available in the full version of the code.
请注意,getStringFromInputStream()是一个接收InputStream并将其内容返回为String的方法。该方法的实现可以在完整版的代码中找到。
We don’t have to copy the whole content of the InputStream, we can copy a range of the content to a given OutputStream using the copyRange() method:
我们不必复制InputStream的全部内容,我们可以使用copyRange()方法将内容的一个范围复制到一个给定的OutputStream。
@Test
public void whenCopyRangeOfInputStreamToOutputStream_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
String outputFileName = "src/test/resources/output.txt";
File outputFile = new File(outputFileName);
InputStream in = new FileInputStream(inputFileName);
OutputStream out = new FileOutputStream(outputFileName);
StreamUtils.copyRange(in, out, 1, 10);
assertTrue(outputFile.exists());
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(inputFileContent.substring(1, 11), outputFileContent);
}
As we can see here, the copyRange() takes four parameters, the InputStream, the OutputStream, the position to start copying from, and the position to end copying. But what if the specified range exceeds the length of the InputStream? The method copyRange() then copies up to the end of the stream.
正如我们在这里看到的,copyRange()需要四个参数,InputStream,OutputStream,从哪个位置开始复制,以及结束复制的位置。但是如果指定的范围超过了InputStream的长度怎么办?方法copyRange()然后复制到流的末端。
Let’s see how we can copy the content of a String to a given OutputStream:
让我们看看如何将一个String的内容复制到一个给定的OutputStream。
@Test
public void whenCopyStringToOutputStream_thenCorrect() throws IOException {
String string = "Should be copied to OutputStream.";
String outputFileName = "src/test/resources/output.txt";
File outputFile = new File(outputFileName);
OutputStream out = new FileOutputStream("src/test/resources/output.txt");
StreamUtils.copy(string, StandardCharsets.UTF_8, out);
assertTrue(outputFile.exists());
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(outputFileContent, string);
}
The method copy() takes three parameters – the String to be copied, the Charset that we want to use to write to the file, and the OutputStream that we want to copy the content of the String to.
方法copy()需要三个参数–要复制的String、我们要用来写入文件的Charset以及我们要将String的内容复制到的OutputStream。
Here is how we can copy the content of a given InputStream to a new String:
下面是我们如何将一个给定的InputStream的内容复制到一个新的String。
@Test
public void whenCopyInputStreamToString_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
InputStream is = new FileInputStream(inputFileName);
String content = StreamUtils.copyToString(is, StandardCharsets.UTF_8);
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
assertEquals(inputFileContent, content);
}
We can also copy the content of a given byte array to an OutputStream:
我们也可以将一个给定的字节数组的内容复制到一个OutputStream。
public void whenCopyByteArrayToOutputStream_thenCorrect() throws IOException {
String outputFileName = "src/test/resources/output.txt";
String string = "Should be copied to OutputStream.";
byte[] byteArray = string.getBytes();
OutputStream out = new FileOutputStream("src/test/resources/output.txt");
StreamUtils.copy(byteArray, out);
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(outputFileContent, string);
}
Or, we can copy the content of a given InputStream into a new byte array:
或者,我们可以将一个给定的InputStream的内容复制到一个新的字节数组中。
public void whenCopyInputStreamToByteArray_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
InputStream is = new FileInputStream(inputFileName);
byte[] out = StreamUtils.copyToByteArray(is);
String content = new String(out);
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
assertEquals(inputFileContent, content);
}
4. Other Functionality
4.其他功能
An InputStream can be passed as an argument to the method drain() to remove all the remaining data in the stream:
一个InputStream可以作为参数传递给drain()方法,以删除流中的所有剩余数据。
StreamUtils.drain(in);
We can also use the method emptyInput() to get an efficient empty InputStream:
我们还可以使用方法emptyInput()来获得一个有效的空InputStream。
public InputStream getInputStream() {
return StreamUtils.emptyInput();
}
There are two overloaded methods named nonClosing(). An InputStream or an OutputStream can be passed as an argument to these methods to get a variant of InputStream or OutputStream that ignores calls to the close() method:
有两个名为nonClosing()的重载方法。一个InputStream或一个OutputStream可以作为参数传递给这些方法,以获得一个InputStream或OutputStream的变体,它忽略了对close()方法的调用。
public InputStream getNonClosingInputStream() throws IOException {
InputStream in = new FileInputStream("src/test/resources/input.txt");
return StreamUtils.nonClosing(in);
}
5. Conclusion
5.结论
In this quick tutorial, we have seen what StreamUtils are. We’ve also covered all of the methods of the StreamUtils class, and we’ve seen how we can use them.
在这个快速教程中,我们已经看到了什么是StreamUtils。我们还介绍了StreamUtils类的所有方法,以及我们如何使用它们。
The full implementation of this tutorial can be found over on GitHub.
本教程的完整实现可以在GitHub上找到over。