当前位置:网站首页>Minio文件下载问题——inputstream:closed
Minio文件下载问题——inputstream:closed
2022-07-06 09:17:00 【阿杆.】
前言
最近在搭建一个简单的博客系统,由于上传下载图片是个比较大的需求,然后我又 比较穷 想挑战一下自己,就使用 Minio
来搭建的 oss
服务。官网:https://min.io/。
为了节省大家的时间,我先写个简短的概述,以便大家判断要不要继续往下看:
在使用minio进行文件下载的时候,代码一直报错 java.io.IOException: closed
,最终发现原来是因为 try () {}
语法问题所导致的。
起因
其下载 object 的方法,大概是传入文件名然后返回一个InputStream
,我要做的是把获取到的流,通过controller返回到前端。
我的思路是把stream直接返回到前端,而不在本地进行下载。那当然需要封装一个工具类 MinioUtils
,然后去调用工具类中的方法,先获取到 inputStream
,然后再在 controller
层去做转换。
经过
尝试过很多方法,也参考了很多博客,一直弄不出来,一直报错 java.io.IOException: closed
,我直接人傻了,关键是我代码里也没调用 stream.close();
啊!
我就想着,会不会是因为不确定字节流的长度,所以提前结束了下载,主要是我对http协议只停留在了解的地步,并不太懂response里面的各种参数,也不确定我写的代码里,会不会有某个方法自动帮我计算好这个长度。于是我就用 stream.available();
去获取它的长度,并且根据此来定义一个byte数组,但是这样也不对,当我调用这个方法的时候,代码就已经报 closed 的错误了。。。
我以为可能是 minio 的问题,曾一度想放弃minio,但是又想着我都弄了这么久了,就放弃有点不划算。
原因
花了两天时间,终于找了问题所在。其实并非是接口的问题,而是Java的 try () {} 语法问题。
public void downloadFile(String fileName) throws Exception {
try (InputStream inputStream = minioClient.getObject(minioConfig.getBucketName(), storePath))
{
return inputStream;
} catch (Exception e) {
logger.error("文件下载异常");
e.printStackTrace();
}
}
// 上面的代码看似没有调用 closed(); ,但实际上在return完之后就已经调用了
// 这是因为使用的 try () {} 语法,在退出 语句块{} 时,就会自动调用closed方法释放资源
解决方法
由于这个原因,导致我的代码一直报错,找到原因之后,问题自然就解决了,下面提供两种解决方法:
// 将输入流传入进来处理
public void downloadFile(String fileName, ServletOutputStream outputStream) throws Exception {
try (InputStream inputStream = minioClient.getObject(GetObjectArgs
.builder()
.bucket(bucketName)
.object(fileName)
.build());
) {
IOUtils.copy(inputStream, outputStream);
} catch (Exception e) {
logg.error("文件下载异常");
e.printStackTrace();
}
}
// 或者把语法换成普通的try{}catch{}
public InputStream download(String fileName) throws Exception {
try {
return minioClient.getObject(GetObjectArgs
.builder()
.bucket(bucketName)
.object(fileName)
.build());
} catch (Exception e) {
e.printStackTrace();
throw new Exception("文件下载失败");
}
}
后记
解决之后,再回头看看原来看的博客和官方文档,好像他们大都是这样写的,其实并没有很大的问题,只是因为我想做一个这样的封装,所以导致我的代码思路即使跟他们一样,但是执行出来却得到了不同的结果。
边栏推荐
- Pytorch实现简单线性回归Demo
- 共用体(union)详解【C语言】
- Redis 缓存更新策略,缓存穿透、雪崩、击穿问题
- Vscode basic configuration
- 关键字 inline (内联函数)用法解析【C语言】
- ES6语法总结--上篇(基础篇)
- Comparison of solutions of Qualcomm & MTK & Kirin mobile platform USB3.0
- C语言,log打印文件名、函数名、行号、日期时间
- Basic operations of databases and tables ----- view data tables
- Reading notes of difficult career creation
猜你喜欢
随机推荐
Common properties of location
Kconfig Kbuild
AMBA、AHB、APB、AXI的理解
JS object and event learning notes
ESP8266通过Arduino IDE连接Onenet云平台(MQTT)
Types de variables JS et transformations de type communes
RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED
Inline detailed explanation [C language]
高通&MTK&麒麟 手機平臺USB3.0方案對比
基于Redis的分布式锁 以及 超详细的改进思路
优先级反转与死锁
Detailed explanation of 5g working principle (explanation & illustration)
Générateur d'identification distribué basé sur redis
OPPO VOOC快充电路和协议
Esp8266 uses Arduino to connect Alibaba cloud Internet of things
Whistle+switchyomega configure web proxy
gcc 编译选项
Basic operations of databases and tables ----- view data tables
js 变量作用域和函数的学习笔记
The first simple case of GNN: Cora classification