当前位置:网站首页>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("文件下载失败");
}
}
后记
解决之后,再回头看看原来看的博客和官方文档,好像他们大都是这样写的,其实并没有很大的问题,只是因为我想做一个这样的封装,所以导致我的代码思路即使跟他们一样,但是执行出来却得到了不同的结果。
边栏推荐
- ES6语法总结--上篇(基础篇)
- [Red Treasure Book Notes simplified version] Chapter 12 BOM
- MySQL占用内存过大解决方案
- JS regular expression basic knowledge learning
- Page performance optimization of video scene
- IOT system framework learning
- Pat 1097 duplication on a linked list (25 points)
- js题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
- ARM PC=PC+8 最便于理解的阐述
- 共用体(union)详解【C语言】
猜你喜欢
高通&MTK&麒麟 手機平臺USB3.0方案對比
ES6 grammar summary -- Part 2 (advanced part es6~es11)
ESP学习问题记录
Pytorch four commonly used optimizer tests
[golang] leetcode intermediate - fill in the next right node pointer of each node & the k-smallest element in the binary search tree
Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
Kaggle竞赛-Two Sigma Connect: Rental Listing Inquiries
open-mmlab labelImg mmdetection
Basic operations of databases and tables ----- creating data tables
機器學習--線性回歸(sklearn)
随机推荐
JS regular expression basic knowledge learning
Kaggle competition two Sigma connect: rental listing inquiries (xgboost)
AMBA、AHB、APB、AXI的理解
程序员老鸟都会搞错的问题 C语言基础 指针和数组
js 变量作用域和函数的学习笔记
Kconfig Kbuild
Characteristics, task status and startup of UCOS III
Amba, ahb, APB, Axi Understanding
Arm pc=pc+8 is the most understandable explanation
STM32 如何定位导致发生 hard fault 的代码段
I2C总线时序详解
Basic operations of databases and tables ----- view data tables
RuntimeError: cuDNN error: CUDNN_ STATUS_ NOT_ INITIALIZED
Dependency in dependencymanagement cannot be downloaded and red is reported
1081 rational sum (20 points) points add up to total points
arduino获取随机数
History object
MySQL占用内存过大解决方案
Stm32f1+bc20+mqtt+freertos system is connected to Alibaba cloud to transmit temperature and humidity and control LED lights
[golang] leetcode intermediate - fill in the next right node pointer of each node & the k-smallest element in the binary search tree