解决InputStream流无法重复使用的问题

一.需求

现在有个需求,要通过InputStream流先去判断文件类型,然后再上传文件,这样就会用到两次InputStream。

二.问题

这个功能之前的同事已经做了一版,一直以为是正常的,毕竟都很久了,但是我用的时候发现上传的文件总是空的,只能去仔细看下代码了。

三.排查

try (InputStream in = inputStream) {//检验文件CheckFileUtil.checkFile(inputStream, FileUtil.extName(filename));LoggerFactory.getLogger(this.getClass()).info("上传文件的文件名="+filename);//上传文件String filePathURL = saveToDisk(in, FileUtil.extName(filename));FileInfo fileInfo = new FileInfo();fileInfo.setId(RandomUtil.simpleUUID());fileInfo.setFileName(filename);fileInfo.setFileType(FileUtil.extName(filename));

之前的代码逻辑是用原来的inputStream去校验,然后用赋值后的in去上传文件,开始看到这里也没发现有什么问题,感觉很正常。

只能去加日志,打断点调试了,最终发现在校验文件之后,不管是inputStream还是in都是空的了,恍然大悟。由于流读过一次就不能再读了。

四.解决

开始想着去复制一遍这个流就行了,查了下才知道不行,InputStream对象本身不能复制,它也没有实现Cloneable接口。

那就先用byte[]去存储,然后用的时候在转换。调整后的代码

public static byte[] readInputStreamToByteArray(InputStream inputStream) throws IOException {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, bytesRead);}return byteArrayOutputStream.toByteArray();}@Overridepublic FileInfo upload(String filename, Long size, InputStream inputStream) {try (InputStream in = inputStream) {byte[] bytes = readInputStreamToByteArray(in);//检验文件CheckFileUtil.checkFile(new ByteArrayInputStream(bytes), FileUtil.extName(filename));LoggerFactory.getLogger(this.getClass()).info("上传文件的文件名="+filename);//上传文件String filePathUrl = saveToDisk(new ByteArrayInputStream(bytes), FileUtil.extName(filename));

但是这种明显只适用于文件不大的时候,不知道如果文件较大的情况下,该怎么进一步优化,先记录下,后面遇到了再补充

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

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

相关文章

仓库管理系统WMS设计思路

仓库管理系统职能范围 仓库管理系统(Warehouse Management System)是一种通过软件来管理和控制仓库操作的系统。制造企业仓库管理系统的职能范围一般包括:入库管理、出库管理、库存管理、订单管理、物流管理等。 1. 入库管理 入库管理是仓库管理系统中的重要环节。…

自然语言处理 TF-IDF

✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…

Cesium 问题:遇到加载Cesium时各组件飞出

致敬爱的读者:该问题出现后暂时未找到最优的解决方案,而是将所有组件状态均进行隐藏,大家如果有解决方案可以留言、评论大家一起探讨解决,欢迎大家踊跃说出自己的想法 文章目录 问题分析 问题 在加载 Cesium 时出现各组件的位置不…

NTP时间同步服务器@客户端时钟同步设置

NTP时间同步服务器客户端时钟同步设置 时间同步服务器支持NTP和SNTP网络同步协议,是一款高精度、大容量、高品质的时钟产品。设备采用冗余架构设计,高精度时钟直接来源于北斗、GPS系统中各个卫星的原子钟,通过信号解析驯服本地时钟源&#x…

读书|长期主义

很早之前就看过穷查理宝典,这次重读,在“我不知道,我从来没有弹过”的语句中真正发现了芒格的幽默,也是触发了我对长期主义的重新思考。 这次尝试了一种新的读书方法,先是在书中读到了“长期主义”,又去搜索…

论文笔记:多任务学习模型:渐进式分层提取(PLE)含pytorch实现

整理了RecSys2020 Progressive Layered Extraction : A Novel Multi-Task Learning Model for Personalized Recommendations)论文的阅读笔记 背景模型代码 论文地址:PLE 背景 多任务学习(multi-task learning,MTL)&a…

龙哥风向标 20230620~20230627 GPT拆解

BarberGPT:眨眼间改变发型,保护用户隐私的个人 AI 理发师网站 盈利点:BarberGPT提供了无限的可能性,用户可以在眨眼之间改变自己的发型,并且非常注重用户的隐私。盈利点可以包括付费的发型种类、社交媒体分享推广等。…

防火墙路由

目录 1. 防火墙的智能选路 2. 策略路由 -- PBR 3. 智能选路 --- 全局路由策略 3.1 基于链路带宽的负载分担: 3.2 基于链路质量进行负载分担 3.3 基于链路权重进行负载分担 3.4 基于链路优先级的主备备份 1. 防火墙的智能选路 就近选路 --- 我们希望在访问不同运营商的服…

Vue2 通过.sync修饰符实现数据双向绑定

App.vue <template><div class"app"><buttonv-on:clickisShowtrue>退出按钮</button><BaseDialog:visible.syncisShow></BaseDialog></div> </template><script> import BaseDialog from "./components…

多符号表达式的共同子表达式提取教程

生成的符号表达式&#xff0c;可能会存在过于冗长的问题&#xff0c;且多个符号表达式中&#xff0c;有可能存在相同的计算部分&#xff0c;如果不进行处理&#xff0c;计算过程中会导致某些算式计算多次&#xff0c;从而影响计算效率。 那么多个符号表达式生成函数时&#xf…

[机器学习]KNN——K邻近算法实现

一.K邻近算法概念 二.代码实现 # 0. 引入依赖 import numpy as np import pandas as pd# 这里直接引入sklearn里的数据集&#xff0c;iris鸢尾花 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 切分数据集为训练集和测试…

2024年数学建模美赛 分析与编程

2024年数学建模美赛 分析与编程 1、本专栏将在2024年美赛题目公布后&#xff0c;进行深入分析&#xff0c;建议收藏&#xff1b; 2、本专栏对2023年赛题&#xff0c;其它题目分析详见专题讨论&#xff1b; 2023年数学建模美赛A题&#xff08;A drought stricken plant communi…

python脚本实现浏览器驱动chromedriver的版本自动升级

chromedriver的版本号与chrome浏览器版本不匹配时在运行程序时就会报错 用下面的脚本可以自动安装chromedriver的最新版本到指定路径 from webdriver_manager.utils import get_browser_version_from_os from webdriver_manager.chrome import ChromeDriverManager import re…

Spring JPA与Hibernate学习使用

EntityManager 在使用持久化工具的时候&#xff0c;一般都有一个对象来操作数据库&#xff0c;在原生的Hibernate中叫做Session&#xff0c;在 JPA 中叫做EntityManager&#xff0c;在MyBatis中叫做SqlSession&#xff0c;通过这个对象来操作数据库。 EntityManager是 JPA 中…

比VS Code快得多

Zed 是一款支持多人协作的代码编辑器&#xff0c;底层采用 Rust&#xff0c;且默认支持 Rust&#xff0c;还自带了 rust-analyzer&#xff0c;主打“高性能”。1 月 24 日&#xff0c;备受关注的 Zed 项目宣布正式开源。 Zed 代码库将采用 Copyleft 许可证&#xff0c;其中编辑…

JavaSE——运算符、运算符优先级、API、Scanner

目录 基本的算术运算符 自增自减运算符 赋值运算符 关系运算符 逻辑运算符 三目运算符 运算符优先级 API Scanner 基本的算术运算符 符号作用加-减*乘/除%取余 基本与C语言的基本算术运算符一致 注意&#xff1a;两个整数相除结果还是整数 public static void main…

C++PythonC# 三语言OpenCV从零开发(7):图像的阈值

文章目录 相关链接前言阈值阈值使用代码PythonCCsharpcsharp代码问题 总结 相关链接 C&Python&Csharp in OpenCV 专栏 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程&#xff08;附带课程课件资料课件笔记&#xff09; OpenCV一个窗口同时显示多张图片 …

C 变量

目录 1. C变量 2. C变量定义 2.1 变量初始化 2.2 C中的变量声明 3. C中的左值&#xff08;Lvalues&#xff09;和右值&#xff08;Rvalues&#xff09; 1. C变量 在C语言中&#xff0c;变量可以根据其类型分为以下几种基本类型&#xff1a; 整型变量&#xff1a;用…

自然语言nlp学习 三

4-8 Prompt-Learning--应用_哔哩哔哩_bilibili Prompt Learning&#xff08;提示学习&#xff09;是近年来在自然语言处理领域中&#xff0c;特别是在预训练-微调范式下的一个热门研究方向。它主要与大规模预训练模型如GPT系列、BERT等的应用密切相关。 在传统的微调过程中&a…

Mac 上 Ln 指令使用说明

ln指令 ln 是 Mac 中又一个非常重要命令&#xff0c;它的功能是为某一个文件在另外一个位置建立一个同不的链接&#xff0c;这个命令最常用的参数是 -s&#xff0c;具体用法是&#xff1a;ln –s 源文件 目标文件。 实例&#xff1a; /Users/apple/Desktop git:(master) ✗&g…