Minio上传url资源文件,文件内容不全的问题

news2024/11/14 4:04:35

遇到问题

使用minio-client时候上传文件为url链接时候,上传inputstream流出现了文件上传成功,但是文件内容缺失,无法正常打开!

在这里插入图片描述
在这里插入图片描述

先看看基本的依赖和配置代码:

pom.xml依赖

     <!-- tika MIME检测机制 -->
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>3.0.0-BETA2</version>
        </dependency>
        <!-- minio     -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.11</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.27</version>
        </dependency>

minio配置

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    private String accessKey;

    private String secretKey;

    private String url;

    private String bucketName;

    @Bean
    public MinioClient minioClient(){
        return MinioClient.builder()
                .region("cn-north-1")
                .endpoint(url)
                .credentials(accessKey,secretKey)
                .build();
    }

}

上传文件代码

    /**
     *  url 上传
     *
     * @param urlStr        urlStr
     * @param bucketName bucket名称
     * @param fileName   文件名称
     * @return {@link String }
     */
    public String upload(String urlStr ,String bucketName, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.connect();
            // 得到网络返回的输入流
            InputStream inputStream = conn.getInputStream();
            String contentType = new Tika().detect(inputStream);
            String extension = MimeTypes.getDefaultMimeTypes().forName(contentType).getExtension();

            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName + extension)
                    .stream(inputStream, inputStream.available(), -1)
                    .contentType(contentType)
                    .build());
            // 需要设置为public
            return fileName + extension;
        } catch (Exception e) {
            log.error("minio上传文件错误:{}", e.getMessage(), e);
            throw new RuntimeException("minio上传文件错误:" + e.getMessage(), e);
        }
    }

debug启动的问题

多次上传发现inputStream.available()的长度每次都不一样,看一下源码这个available方法返回的值是怎么个事
在这里插入图片描述在这里插入图片描述

哦吼,问题找到了!!! 他一直在估计这个输入流的长度,就没有直接读出来,那么问题来了,我只能使用File类来获取其长度吗?

还有解法: “A subclass’s implementation of this method may choose to throw an IOException if this input stream has been closed by invoking the close() method”,那还是有一些子类的Stream方法能实现返回流中的字节总数,百度了一下,发现有FileInputStream,ByteArrayInputStream,BufferedInputStream类能完成统计流中字节数的统计!

新增处理类

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

@Slf4j
public class FileUtil {

    /**
     * 通过网络地址获取文件InputStream(持续获取)
     *
     * @param urlStr 地址
     * @return inputStream
     */
    public static InputStream returnByteStream(String urlStr) {
        if (StrUtil.isEmpty(urlStr) || !urlStr.matches("^(http|https)://.*$")) {
            throw new RuntimeException("url存在问题,请检查是否可以下载!");
        }
        try {
            // 利用HttpURLConnection对象,我们可以从网络中获取网页数据.
            URL url = new URL(urlStr);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.connect();
            // 得到网络返回的输入流
            InputStream inputStream = conn.getInputStream();
            // 转化为ByteArrayInputStream
            byte[] data = stream2ByteArray(inputStream);
            return new ByteArrayInputStream(data);
        } catch (Exception e) {
            log.error("url文件下载错误!");
            throw new RuntimeException("url文件下载错误!错误原因是:" + e.getMessage(), e);
        }

    }

    /**
     * 获取流中字节数组
     *
     * @param inputStream 输入流
     * @return {@link byte[] }
     */
    public static byte[] stream2ByteArray(InputStream inputStream) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // 处理大文件流
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        try {
            byte[] buffer = new byte[2048];
            int len = -1;
            while ((len = bis.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            return outputStream.toByteArray();
        } catch (Exception e) {
            log.error("文件处理出现问题,{}", e.getMessage());
            throw new RuntimeException(e);
        } finally {
            try {
                outputStream.close();
                inputStream.close();
            } catch (Exception e) {
                log.error("输入输出流关闭错误,{}", e.getMessage());
            }
        }
    }
}

修改后代码

   /**
     *  url 上传
     *
     * @param urlStr        urlStr
     * @param bucketName bucket名称
     * @param fileName   文件名称
     * @return {@link String }
     */
    public String upload(String urlStr ,String bucketName, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            // 此处获取到流并且计算出长度
            InputStream inputStream = FileUtil.returnByteStream(urlStr);
            String contentType = new Tika().detect(inputStream);
            String extension = MimeTypes.getDefaultMimeTypes().forName(contentType).getExtension();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName + extension)
                     // 此处的inputStream.available()长度就是文件的长度
                    .stream(inputStream, inputStream.available(), -1)
                    .contentType(contentType)
                    .build());
            // 需要设置为public
            return fileName + extension;
        } catch (Exception e) {
            log.error("minio上传文件错误:{}", e.getMessage(), e);
            throw new RuntimeException("minio上传文件错误:" + e.getMessage(), e);
        }
    }

至此,minio上传文件后,文件可以正常打开了!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android NestedScrollView+TabLayout+ViewPager+ 其它布局,ViewPager 不显示以及超出屏幕不显示问题

前言 此场景为 NestedScrollView 嵌套多个布局 &#xff0c;大致结构为 NestedScrollViewTabLayoutViewPagerfragment 其它View,如下图 &#xff0c; 一、ViewPager 设置高度才会显示内容问题 原因&#xff1a;NestedScrollView 计算高度先于 ViewPager 渲染前&#xff0c;所…

电商跨境电商商城系统/网上商城接口/电商数据接口详情

电商API接口背景&#xff1a;电商运营中&#xff0c;数据分析这项工作越来越重要&#xff0c;许多品牌方也越来越热衷去做电商数据分析。不过&#xff0c;全面的数据该如何获取呢&#xff0c;此时&#xff0c;电商数据接口的重要性便凸显出来了。 电商API数据接口主要有以下特…

go 读取excel

一、安装依赖 go get github.com/tealeg/xlsx二、main.go package mainimport "fmt" import "github.com/tealeg/xlsx"type Student struct {Name stringSex string }func (student Student) show() {fmt.Printf("Name:%s Sex:%s\r\n", stude…

OneNet平台替换腾讯云IOT平台(2024年6月)

文章目录 一、前言二、OneNet替换腾讯云IOT三、修改说明&#xff1a;STM32代码3.1 替换MQTT三元组&#xff08;常规操作&#xff09;3.2 修改上传的数据格式。 四、修改说明&#xff1a;服务器配置 一、前言 从2024年06月20日起&#xff0c; 新注册腾讯云物联网开发平台的用户…

浅谈人工智能技术,对社会经济变革的思考

原创 冰锋血骨 芯原创 2024年09月23日 15:44 北京 英国DeepMind公司研发的AlphaGo在2016年3月第一次战胜了围棋世界冠军韩国棋手李世石,人工智能(AI,Artificial Intelligence)第一次映入公众的视野。人工智能是什么?人工智能会想人一样思考吗?人工智能可以应用在哪些领域…

如何用AI论文生成工具撰写一篇高质量的成人教育毕业论文

撰写一篇高质量的成人教育毕业论文并不简单&#xff0c;它有一定的步骤和策略。锐智AI今天就总结了一些关键的步骤&#xff0c;希望对即将毕业的你顺利完成论文写作&#xff1a; 介绍之前简单说下锐智AI&#xff0c;它是一款集论文大纲生成、内容填充、文献引用、查重修改于一…

猎板PCB揭秘厚铜板技术的最新进展

在电子设备不断追求更高性能与更小尺寸的今天&#xff0c;PCB厚铜板技术因其卓越的导电性和散热性能&#xff0c;成为提升电子产品性能的关键材料。猎板PCB今天针对厚铜板的最新技术进展、应用领域及制造流程&#xff0c;为您提供全面的技术资料。 一、PCB厚铜板技术概览 PCB厚…

SpringCloud入门(六)Nacos注册中心(下)

一、Nacos环境隔离 Nacos提供了namespace来实现环境隔离功能。 nacos中可以有多个namespace。namespace下可以有group、service等。不同namespace之间相互隔离&#xff0c;例如不同namespace的服务互相不可见。 使用Nacos Namespace 环境隔离 步骤&#xff1a; 1.在Nacos控制…

007——递归(树的前置知识点)

目录 创建副本 递归 直接调用 间接调用 递归的具体流程又是什么样子的&#xff1f; 递归函数的组成&#xff1a; 递归可以用来解决什么问题&#xff1f; 例子1&#xff1a;求和问题 例子2&#xff1a;斐波那契数列 补充&#xff1a; 说到递归&#xff0c;我们可以简单…

Spring Boot实用小技巧5 - 第527篇

《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《国内最全的Spring Boot系列之七》 SpringBoot …

10KV并网分布式光伏电力监控解决方案

一、分布式光伏并网要求 Q/GDW1480-2015 《分布式电源接入电网技术规定》&#xff1a;分布式电源并网电压等级可根据各并网点装机容量进行初步选择&#xff0c;推荐如下&#xff1a; 8kW 及以下可接入220V&#xff1b; 8kW~400kW可接入380V&#xff1b; 400kW~6MW可接入10k…

MySQL篇(锁机制 基本介绍、全局锁\表级锁\行锁、悲观锁\乐观锁)

目录 讲解一&#xff1a;基本介绍 一、简介 二、MySQL中的锁 1. 锁粒度分类&#xff08;三类&#xff09; 讲解二&#xff1a;全局锁\表级锁\行锁 一、全局锁 1. 简介 2. 不加全局锁的问题 3. 加全局锁的好处 4. 操作 加全局锁 数据备份 释放锁 5. 特点 二、表级…

计算机毕业设计 基于Flask+Vue的博客系统 Python毕业设计 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

稀土抗菌剂马桶盖,让家庭清洁更上一层楼

稀土元素&#xff0c;作为现代工业中的“维生素”&#xff0c;在抗菌领域的表现尤为突出。稀土抗菌剂是一种通过阻碍细菌代谢活动&#xff0c;抑制细菌繁殖的高效抗菌材料。与普通抗菌技术相比&#xff0c;稀土抗菌剂具有更强的持久性和安全性&#xff0c;能够长期有效地抑制细…

Kolors模型部署指南

一、模型介绍 Kolors 是快手 Kolors 团队基于潜在扩散的大规模文本转图片生成模型。经过数十亿个文本-图片对的训练&#xff0c;Kolors 在视觉质量、复杂语义准确性和中英文文本渲染方面均比开源和闭源模型具有显著优势。此外&#xff0c;Kolors 支持中英文输入&#xff0c;在…

GPT-4o能玩《黑神话》!精英怪胜率超人类,无强化学习纯大模型方案

AI玩黑神话&#xff0c;第一个精英怪牯护院轻松拿捏啊。 有方向感&#xff0c;视角也没有问题。 躲闪劈棍很丝滑。 甚至在打鸦香客和牯护院时&#xff0c;AI的胜率已经超过人类。 而且是完全使用大模型玩&#xff0c;没有使用强化学习。 阿里巴巴的研究人员们提出了一个新型V…

派可数据:解锁数据潜力,驱动业务价值新增长

前 言 当前&#xff0c;企业数字化转型经过初始探索阶段&#xff0c;各行各业进入高速发展百花齐放的创新应用新阶段。创新应用阶段的核心是企业应用先进的数字技术和工具&#xff0c;对企业多年在全领域积累的各类数据&#xff0c;包括财务、业务、生产、设计、设备、工艺等结…

Python编码系列—Python模板方法模式:定义算法骨架,让子类实现细节

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

STM32F407单片机编程入门(十六) DMA详解及ADC-DMA方式采集含源码

文章目录 一.概要二.STM32F407VET6单片机DMA外设特点三.STM32F407单片机DMA内部结构图四.DMA各通道请求五.STM32F407VET6单片机ADC-DMA采集例程六.工程源代码下载七.小结 一.概要 基本概念&#xff1a; DMA是Direct Memory Access的首字母缩写,是一种完全由硬件执行数据交换的…

RK3568教学实验箱_操作教程:5-15 直流电机控制实验

一、产品简介 TL3568-PlusTEB人工智能实验箱 国产高性能处理器 64 位 4 核低功耗 2.0 GHz超高主频 1T 超高算力 NPU 兼容鸿蒙等国产操作系统 二、实验目的 1、熟悉Qt程序的开发流程&#xff1b; 2、掌握Qt Creator的基础开发使用&#xff1b; 3、通过编写Qt程序实现直流…