Minio文件下载问题——inputstream:closed

前言

最近在搭建一个简单的博客系统,由于上传下载图片是个比较大的需求,然后我又 比较穷 想挑战一下自己,就使用 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("文件下载失败");
    }
}

后记

解决之后,再回头看看原来看的博客和官方文档,好像他们大都是这样写的,其实并没有很大的问题,只是因为我想做一个这样的封装,所以导致我的代码思路即使跟他们一样,但是执行出来却得到了不同的结果。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿杆.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值