java 输入流输出流干净使用

输入流和输出流都有个数据介质,输入流从数据介质中读取数据,输出流往数据介质中写如数据。谈谈在读取数据时将数据读完全,写也一样。

1.输入流

InputStream 主要有三个读方法:
public abstract int read() throws IOException;

public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

public int read(byte b[], int off, int len) throws IOException
  • read()是从数据介质中读一个字节,当然每次读一个字节效率不高,所以有了下面的方法,一次将更多的字节填充到数组中
  • read(byte[]) 是尝试往 参数字节数组中填充数据,是尝试,所以有多种情况会填充失败,比如一个网络连接有1024字节,但只是暂时到达了512字节,所以第一次不能读完1024。或者参数数组有1024大小,但数据也只有512,也不能把参数数组填充满。
  • read(byte b[], int off, int len) 往参数数组中填充数据,从off为数组起点索引,填充长度为len。
  • 三个方法都以 -1 为返回值标志流中没有数据。
  • public int available() 流可读取的最少字节数,这是暂时可用的字节数,并不是全部。如果想要程序先读取一次,即使没有读完,也要进行其他程序,可以new byte[available大小] 然后去读

所以以下代码,不能保证读全数据:

        InputStream urlConnectionInputStream = urlConnection.getInputStream();
        byte[] result = new byte[urlConnectionInputStream.available()];
        urlConnectionInputStream.read(result);

下面代码可以:但contentLength变量是数据的长度,这是通过业务上其他方法获得的,如果你不能获得数据长度,比如随便给result数组大小为1024,如果数据介质真实大小超过了1024,就会数组越界。

最后记得关闭流、

        InputStream urlConnectionInputStream = urlConnection.getInputStream();
        byte[] result = new byte[contentLength];
        int byteToRead = 0;
        while (byteToRead<contentLength){
            int read = urlConnectionInputStream.read(result, byteToRead, contentLength-byteToRead);
            if (read==-1)
                break;
            byteToRead+=read;
        }
        urlConnectionInputStream.close();

2.输出流

输出流输出干净,主要是记得刷新流和关闭流,刷新流会强迫缓冲区发送数据,否则有一些尾端数据在缓冲区没法送出去。

而不关闭流则会造成资源泄漏等问题。

这两个api都会抛出异常,catch起来很麻烦,所以这样写很方便:

        //try()中的输出流,java会自动调用close
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            InputStream inputStream = resourceLoader.getResource("classpath:excelTemplate/alarmTemplate.xlsx").getInputStream();
            //将文件填充到字节流
            EasyExcel.write(outputStream).withTemplate(inputStream).sheet("alarm").doFill(exportList);

            outputStream.flush();
        } catch (IOException e) {
            logger.error("read or write excel failed");
        }

3.URL类

new URL("http://xxx").openConnection().getContentLength();

可以得到数据的准确长度,但是通过流不可以。

猜你喜欢

转载自blog.csdn.net/u014203449/article/details/104966619
今日推荐