Spring 中StreamUtils教程详解编程语言

本文我们介绍StreamUtils类使用。StreamUtils是spring中用于处理流的类,是java.io包中inputStream和outputStream,不是java8中Steam。使用时仅依赖spring-core,主要需要了解几个静态方法。

拷贝Stream

StreamUtils类包括几个重载copy()方法,也包括几个变体:

  • copyRange()
  • copyToByteArray()
  • copyString()

我们能不依赖任何jar实现拷贝流。然而,这样会使代码冗难读,不易理解。

为了简单起见,我们省略关闭流,实际应用中需要调用close()方法关闭输入或输出流。

让我们看看如何拷贝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); 
}

 

创建的新文件包括inputStream中的内容。

其中getStringFromInputStream() 方法负责取inputStream内容并返回字符串。

import org.apache.commons.io.IOUtils; 
import org.springframework.util.StreamUtils; 
 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.StringWriter; 
 
public class CopyStream { 
    public static String getStringFromInputStream(InputStream input) throws IOException { 
        StringWriter writer = new StringWriter(); 
        IOUtils.copy(input, writer, "UTF-8"); 
        return writer.toString(); 
    } 
 
    public InputStream getNonClosingInputStream() throws IOException { 
        InputStream in = new FileInputStream("src/test/resources/input.txt"); 
        return StreamUtils.nonClosing(in); 
    } 
}

 

我们也可以不拷贝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); 
}

 

如上述代码所示,copyRange方法有四个参数,inputStream,outputStream,开始拷贝位置,结束拷贝位置。如果我们指定的长度超过inputStream的长度呢?copyRange方法仅拷贝至流的结尾。

下面看看如何拷贝字符串至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); 
}

 

copy方法带三个参数:被拷贝的字符串,写文件时指定的字符集,指定目的地(outputStream)。

我们也可以把给定的inputStream内容拷贝为字符串:

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

 

也可以拷贝字节数组的内容至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); 
}

 

同样,也可以拷贝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); 
}

 

其他功能

inputStream可以作为参数传递给drain()方法,删除流中所有剩余数据:

StreamUtils.drain(in);

 

也可以使用emptyInput()方法获得一个有效空输入流:

public InputStream getInputStream() { 
    return StreamUtils.emptyInput(); 
}

 

还有两个重载方法nonClosing(),inputStream和outputStream流可以作为参数,用于返回无需关闭的inputStream和outputStream流。

public InputStream getNonClosingInputStream() throws IOException { 
    InputStream in = new FileInputStream("src/test/resources/input.txt"); 
    return StreamUtils.nonClosing(in); 
}

 

总结

本文介绍了StreamUtil类及其所有方法,利用可以大大简单代码,提高开发效率。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/15726.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论