当前位置:网站首页>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("文件下载失败");
}
}
后记
解决之后,再回头看看原来看的博客和官方文档,好像他们大都是这样写的,其实并没有很大的问题,只是因为我想做一个这样的封装,所以导致我的代码思路即使跟他们一样,但是执行出来却得到了不同的结果。
边栏推荐
- Fashion-Gen: The Generative Fashion Dataset and Challenge 论文解读&数据集介绍
- ESP learning problem record
- Arduino gets the length of the array
- 嵌入式启动流程
- Types de variables JS et transformations de type communes
- Kconfig Kbuild
- C language, log print file name, function name, line number, date and time
- Custom view puzzle getcolor r.color The color obtained by colorprimary is incorrect
- open-mmlab labelImg mmdetection
- Important methods of array and string
猜你喜欢
Amba, ahb, APB, Axi Understanding
Stm32f1+bc20+mqtt+freertos system is connected to Alibaba cloud to transmit temperature and humidity and control LED lights
Custom view puzzle getcolor r.color The color obtained by colorprimary is incorrect
JS object and event learning notes
Pat 1097 duplication on a linked list (25 points)
open-mmlab labelImg mmdetection
open-mmlab labelImg mmdetection
Kaggle竞赛-Two Sigma Connect: Rental Listing Inquiries
A possible cause and solution of "stuck" main thread of RT thread
Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
随机推荐
STM32 how to locate the code segment that causes hard fault
ES6 grammar summary -- Part 2 (advanced part es6~es11)
Mp3mini playback module Arduino < dfrobotdfplayermini H> function explanation
Missing value filling in data analysis (focus on multiple interpolation method, miseforest)
Togglebutton realizes the effect of switching lights
Gallery's image browsing and component learning
冒泡排序【C语言】
Page performance optimization of video scene
列表的使用
Unit test - unittest framework
JS数组常用方法的分类、理解和运用
Raspberry pie tap switch button to use
Who says that PT online schema change does not lock the table, or deadlock
【ESP32学习-1】Arduino ESP32开发环境搭建
Pytorch实现简单线性回归Demo
JS variable types and common type conversions
Pat 1097 duplication on a linked list (25 points)
OPPO VOOC快充电路和协议
Basic operations of databases and tables ----- classification of data
Priority inversion and deadlock