复用InputStream

什么是 InputStream

InputStream就是Java标准库提供的最基本的输入流。它位于java.io这个包里。java.io包提供了所有同步IO的功能。
要特别注意的一点是,InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类

为什么要复用 InputStream

  • 在实际的工作当中,某些场合下我们常常会需要多次读取一个InputStream的需求,比如:从流中提取文本、文档格式转换、文件复制移动等。
  • 但InputStream具有不可重复使用的特性,如果第一次使用后就关闭了流,第二次使用就会报出java.io.IOException: Stream Closed的异常,如果第一次使用没有关闭流,第二次使用的时候读取到的字节数就是0,因为在InputStream读取的时候,会有一个pos指针,他指示每次读取之后下一次要读取的起始位置,当读到最后一个字符的时候,pos指针不会进行重置。

方法一【不建议使用】

先将InputStream转为string,需要用到的时候再将string转为InputStream
注意:读取excel等office文件时会损坏文件流

  1. 将InputStream转为string
public static String inToStr(InputStream in){
	return new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining(System.lineSeparator()));
}
  1. 将string转为InputStream
public static InputStream strToIn(String str){
	return new ByteArrayInputStream(str.getBytes());
}

方法二【建议使用】

转为ByteArrayInputStream,每次使用完都使用reset方法将指针指向开头

  1. 将InputStream转为ByteArrayInputStream
/**
 1. 将InputStream转换成ByteArrayOutputStream
 */
public static ByteArrayOutputStream toOutByteStream(InputStream in) throws IOException {
    ByteArrayOutputStream out =new ByteArrayOutputStream();
    byte[] buffer=new byte[1024];
    int len;
    while((len=in.read(buffer))>-1){
        out.write(buffer,0,len);
    }
    out.flush();
    in.close();
    return out;
}
/**
 * InputStream转成ByteArrayInputStream
 */
public static ByteArrayInputStream toByteArrayInputStream(InputStream in) throws IOException {
   return getInput(toOutByteStream(in));
}
  1. 重置指针
public static void reset(ByteArrayInputStream in){
    if (in != null){
        in.reset();
    }
}
  1. 实际使用
public void importExcel(InputStream stream) {
    ByteArrayInputStream newIn = IoUtil.toByteArrayInputStream(stream);//转为ByteArrayInputStream(有异常自己处理下)
    ExcelReader reader = Excel.getReader(newIn);//获取reader
    IoUtil.reset(newIn);//重置指针
    List<Sheet> sheets = reader.getSheets();//获取所有sheet
    for (int i = 0; i < sheets.size(); i++) {
        try{
            Sheet sheet = sheets.get(i);
            //获取列表元素
            List<ModelAtomExcelVo> datas = ExcelUtil.read(T.class,sheet.getSheetName(),newIn);
            IoUtil.reset(newIn);//重置指针
            System.out.println(datas);
        }catch (Exception e){
            log.error("", e);
        }
    }
    //释放资源
    IoUtil.close(stream,newIn)
}

小结

其中还可以将InputStream缓存起来,但是对于内存的开销会比较大,个人认为方法二已经可以满足需求了

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泽泽泽json

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值