zoukankan      html  css  js  c++  java
  • 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类及其所有方法,利用可以大大简单代码,提高开发效率。

  • 相关阅读:
    3.redis认证
    2.redis-help使用,基本命令
    安卓使用merge标签和include优化UI布局
    安卓数据存储之ContentProvider
    安卓数据存储之SQLLite
    安卓数据存储之SharePreference
    安卓数据存储之sdcard存储
    java解析json之gjson和fastjson
    Android Volley完全解析(一),初识Volley的基本用法
    使用Pull解析Xml文件
  • 原文地址:https://www.cnblogs.com/shamo89/p/9095325.html
Copyright © 2011-2022 走看看