最近上传阿里云的时候同一个文件上传两个服务地址,第一个文件读取以后第二个再去读取就拿不到了。代码如下:

   //内网上传OSS获取key值
String ossKey = OSSClientUtil.getOSSURL(endpoint, accessKeyId, accessKeySecret, bucketName, key, inputStream);
//外网上传OSS获取key值
String outOssLink = OSSClientUtil.getOutOSSLink(outEndpoint, outAccessKeyId, outAccessKeySecret, outBucketName, key,
inputStream); 

导致第二次上传失败。

Java中的Inputstream是不能重复读取的。
但是有没有想过,InputStream为什么不能重复读呢?
其实要回答“为什么”这个问题很简单,就是人家接口就是这么设计的,不能重复读。
所以今天要讨论的问题更像是:Java的InputStream为什么要设计为不能重复读?
关于InputStream为什么不能重复读取,网上也各有说法:
有的同学说:
“InputStream就类比成一个杯子,杯子里的水就像InputStream里的数据,你把杯子里的水拿出来了,杯子的水就没有了,InputStream也是同样的道理。”
比喻的非常好,让我们从直观上认识了InputStream为什么不能重复被读。
也有的同学从更深的代码角度去分析:
“在InputStream读取的时候,会有一个pos指针,他指示每次读取之后下一次要读取的起始位置,当读到最后一个字符的时候,pos指针不会重置。”
说的也有道理,就是说InputStream的读取是单向的。但是并不是所有的InputStream实现类都是这样的实现方式。

Java 的List内部是使用数组实现的,遍历的时候也有一个pos指针。但是没有说List遍历一个第二次遍历就没有了。第二次遍历是创建新的Iterator,所以pos也回到了数组起始位置。对于某些InputStream当然可以也这么做。例如:ByteArrayInputStream
ByteArrayInputStream就是将一个Java的byte数组保存到对象里,然后读取的时候遍历该byte数组。

更改以后的代码如下:

public class InputStreamFactory {

    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private byte[] buffer = new byte[1024]; public InputStreamFactory(InputStream input) throws IOException {
int len;
while ((len = input.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
byteArrayOutputStream.flush();
} public InputStream newInputStream() {
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
} }

更改代码:

  InputStreamFactory inputStreamFactory = null;
try {
inputStreamFactory = new InputStreamFactory(inputStream);
//内网上传OSS获取key值
String ossKey = OSSClientUtil.getOSSURL(endpoint, accessKeyId, accessKeySecret, bucketName, key,
inputStreamFactory.newInputStream());
//外网上传OSS获取key值
String outOssLink = OSSClientUtil.getOutOSSLink(outEndpoint, outAccessKeyId, outAccessKeySecret, outBucketName,
key, inputStreamFactory.newInputStream());
} catch (IOException e) {
log.info("读取文件流失败", e);
}

  

InputStream为什么不能被重复读取?的更多相关文章

  1. InputStream流无法重复读取的解决办法

    前言:今天工作的需要需要读取aws云上S3桶里面的PDF数据,第一步能够正常的获取PDF文件的InputStream流,然后,我为了测试使用了IOUtils.toString(is)将流System. ...

  2. Java 利用 ByteArrayOutputStream 和 ByteArrayInputStream 避免重复读取配置文件

    最近参与了github上的一个开源项目 Mycat,是一个mysql的分库分表的中间件.发现其中读取配置文件的代码,存在频繁多次重复打开,读取,关闭的问题,代码写的很初级,稍微看过一些框架源码的人,是 ...

  3. 拦截器中,request中getReader()和getInputStream()只能调用一次,构建可重复读取inputStream的request.

    由于 request中getReader()和getInputStream()只能调用一次 在项目中,可能会出现需要针对接口参数进行校验等问题. 因此,针对这问题,给出一下解决方案 实现方法:先将Re ...

  4. SpringMvc上传文件遇到重复读取InputStream的问题

    文件上传配置: <bean id="multipartResolver" class="org.springframework.web.multipart.comm ...

  5. ServletInputStream的重复读取(多次读取)(转)

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  6. 多线程下不重复读取SQL Server 表的数据

    在进行一些如发送短信.邮件的业务时,我们经常会使用一个表来存储待发送的数据,由后台多个线程不断的从表中读取待发送的数据进行发送,发送完成后再将数据转移到历史表中,这样保证待发送表的数据一般情况下不会太 ...

  7. ASP.NET Core重复读取Request.Body

    //HttpContext context.Request.EnableRewind(); //创建缓冲区存放Request.Body的内容,从而允许反复读取Request.Body的Stream u ...

  8. Java实现inputstream流的复制

    获取到一个inputstream后,可能要多次利用它进行read的操作.由于流读过一次就不能再读了,而InputStream对象本身不能复制,而且它也没有实现Cloneable接口,所以得想点办法. ...

  9. java HttpServletRequest 重复流读取

    在用reset接口的时候,常常会使用request.getInputStream()方法,但是流只能读取一次,一旦想要加上一个过滤器用来检测用户请求的数据时就会出现异常.   在过滤器中通过流读取出用 ...

随机推荐

  1. ASP.NET MVC 常用路由总结

    1.URL模式 路由系统用一组路由来实现它的功能,这些路由共同组成了应用系统URL架构或方案,这种URL架构是应用程序能够识别并能对之做出响应的一组URL,当处理一个输入 请求时,路由系统的工作是将这 ...

  2. react 15.5版本的警告问题

    一.问题描述 前几天从git上拉下一个项目,cnpm i 安装依赖,项目跑起来后,发现有两个警告.之前这个项目都好好的,怎么突然报错了? Warning: Accessing PropTypes vi ...

  3. linux上如何自动获取ip及连接互联网

    1.讲与虚拟机连接网卡设置为net连接 2.BOOTPROTO=dhcp 3.注释原来的ip 4.最后一句网关注释 5.重启网卡 service network restart

  4. 7种方法实现移动端Retina屏幕1px边框效果

    在Reina(视网膜)屏幕的手机上,使用CSS设置的1px的边框实际会比视觉稿粗很多.在之前的项目中,UI告诉我说我们移动项目中的边框全部都变粗了,UI把他的设计稿跟我的屏幕截图跟我看,居然真的不一样 ...

  5. Shell脚本笔记(一)一些零碎的基础知识

    一些零碎的基础知识 一.认识Shell脚本 一)相关概念 Shell是一种命令解释器,作用是按次序执行(遇到子脚本,先执行子脚本的命令)用户输入的命令和程序. Shell脚本语言是弱类型语言,与其他脚 ...

  6. [CC-CMPVIRS]Computer Virus

    [CC-CMPVIRS]Computer Virus 题目大意: 有一张纸带,从左到右被分成了\(n(n\le10^7)\)个格子,在刚开始,第\(i\)个格子上写着数字\(i\).这张纸带被分成了从 ...

  7. Java中的RASP实现

    RSAP RASP是Gartner公司提出的一个概念,称:程序不应该依赖于外部组件进行运行时保护,而应该自身拥有运行时环境保护机制: RASP就是运行时应用自我保护(Runtime applicati ...

  8. Linux之nginx服务

    作业一:nginx服务 1.二进制安装nginx包 2.作为web服务修改配置文件 3.让配置生效,验证配置 [root@localhost ~]# yum -y install epel-relea ...

  9. RMQ(Range MinimumQuery)问题之ST算法

    ST算法------是用来求解给定区间RMQ的最值,本文以最小值为例 ST算法分为两部分 离线预处理(nlogn):运用DP思想,用于求解区间最值,并保存到一个二维数组中. 在线查询 (O(1)):对 ...

  10. 简易RPC框架-SPI

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...