InputStream重用

网上所找到的大多是利用 ByteArrayOutputStreamByteArrayInputStream 之前的相互转换来实现的。
具体看下列代码

InputStream input =  httpconn.getInputStream();
	            
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1 ) {
	baos.write(buffer, 0, len);
}
baos.flush();	           
 
InputStream stream1 = new ByteArrayInputStream(baos.toByteArray());
 
//TODO:显示到前台
 
InputStream stream2 = new ByteArrayInputStream(baos.toByteArray());
 
//TODO:本地缓存

摘抄自这篇博客InputStream重用技巧(利用ByteArrayOutputStream)

秉着 “拿来思考主义” ,上述代码存在着严重的浪费内存以及效率问题;每次复用,需要重新拷贝数组,即浪费了时间,又浪费了空间。显然,这不会是处女座的程序员想要的。

不知道大家想到过这种用法嘛?mark 方法 和 reset 方法结合来实现重用(他们会共用一份存储空间,如果你的没有并发的问题,我觉得使用这个是没问题的)。不过存在某些实现流不支持这两种方法,像 FileInputStream 。不过还好包装器模式的完美之处开始体现,功能性流 BufferedInputStream 可以弥补这个不足。附上代码:

BufferedInputStream bufferedInputStream = new BufferedInputStream(file.getInputStream());
// 这里为什么加一,是因为我们需要重用整个流可读取字节,如果不加1,会失败掉,具体失败原因可以查看异常抛出点
bufferedInputStream.mark(bufferedInputStream.available() + 1);

// 第一次使用 bufferedInputStream 直接使用即可

// 第二次使用 bufferedInputStream ,需要先 reset
bufferedInputStream.reset();

上面也提到,如果有并发的原因,也就是同一个 BufferedInputStream 实例化对象被多个线程使用,这样就会存在问题了。原因也很好理解,BufferedInputStream 实例化对象中存在一些状态,像 pos, markpos 等 ,多线程下修改这些状态就会出现问题了。我给出的解决方案是使用 ThreadLocal ,或者使用文章开头所提到的方法也行。


办法多多,欢迎留言讨论。另外,可能也存在未考虑到的其它情况,希望猿友们能留言给出疑问,也能给后续阅读的博友们起到解读的作用。

由于 available 方法,返回的并不是一个确切值,上述方法的可用性还是有待商酌啊,不过我目前是这样使用的,并未出现问题。

如果你觉得我的文章对你有所帮助的话,欢迎关注我的公众号。赞!我与风来
认认真真学习,做思想的产出者,而不是文字的搬运工。错误之处,还望指出!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值