简单分享下文件下载中心的实现和代码

背景

业务中很常见的场景,就是下载. 而随着业务数据越来越大, 下载的负担也越来越重, 时间越来越久
因此经常会将其做成异步的, 先给前端返回,然后开一个线程去处理. 然后等处理完用户到一个专门的页面下载.

要实现这样的功能, 肯定要把下载的内容存起来:

-- t_train_file_center definitionCREATE TABLE `t_file_center` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`file_name` varchar(200) NOT NULL DEFAULT '' COMMENT '文件名',`create_id` varchar(20) NOT NULL DEFAULT '' COMMENT '创建人',`create_name` varchar(50) NOT NULL DEFAULT '' COMMENT '创建人名字',`status` int(11) NOT NULL DEFAULT '0' COMMENT '状态. 1:进行中, 2:已完成, 3: 已失效, 4:处理失败, -1: 已取消, -2:已删除',`file_path` varchar(500) NOT NULL DEFAULT '' COMMENT '文件路径',`is_delete` int(11) NOT NULL DEFAULT '0' COMMENT '是否物理删除. 1: 是',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',`update_id` varchar(30) NOT NULL DEFAULT '' COMMENT '更新人',`update_name` varchar(50) NOT NULL DEFAULT '' COMMENT '更新人名字',`remark` varchar(1000) DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`),KEY `file_name_IDX` (`file_name`) USING BTREE,KEY `create_id_IDX` (`create_id`) USING BTREE
) ENGINE=InnoDB   DEFAULT CHARSET=utf8mb4 COMMENT='批量文件导出中心';

如果是要实现比如批量压缩后打成压缩包的,还需要一个详情表来记录压缩包里的文件信息

思路

思路大概就是:

  1. 先初始化记录,状态标记为进行中
  2. 返回前端基本信息
  3. 异步处理
  4. 更新结果
  5. 定期删除过期文件(可选)

代码

    /*** 处理文件创建,下载, 直接写入服务器版本* */public String doSaveFile(String filename, Consumer<OutputStream> consumer, ExecutorService executorService) throws IOException {String path = "filecenter/tempfile" + FilesUtils.generateDirPathByTimestamp() + "/" + filename;//获取当前登录人SessionUser user = UserCtxUtil.getCurrentUser();//创建文件,我这个是直接在nas上创建.File file = fileCommonService.createFile(path);//创建文件结束//记录文件path,写入表中Long id = this.saveTempFile(filename, path, Status.PROCESSING, user);if (executorService != null) {//开始处理,如果提供了线程池,异步处理executorService.execute(() -> process(consumer, file, id, user));} else {//同步处理process(consumer, file, id, user);}return path;}/*** 记录到文件中心,默认7天后删除文件** @param path* @return*/@Overridepublic Long saveTempFile(String filename, String path, FileCenterEnum.Status status, SessionUser user) {FileCenter fileCenter = new FileCenter();fileCenter.setFileName(filename);fileCenter.setFilePath(path);fileCenter.setStatus(status.getCode());if (user != null) {fileCenter.setCreateId(user.getEmpNumber());fileCenter.setCreateName(user.getName());fileCenter.setCreateTime(new Date());fileCenter.setUpdateId(user.getEmpNumber());fileCenter.setUpdateName(user.getName());}super.save(fileCenter);return fileCenter.getId();}@Overridepublic void updateStatus(Long id, FileCenterEnum.Status status, String remark, SessionUser user) {FileCenter fileCenter = new FileCenter();fileCenter.setId(id);fileCenter.setStatus(status.getCode());fileCenter.setRemarkremark,1000);if (user != null) {fileCenter.setUpdateId(user.getEmpNumber());fileCenter.setUpdateName(user.getName());fileCenter.setUpdateTime(new Date());}super.updateById(fileCenter);}/*** 处理文件流的写入*/private void process(Consumer<OutputStream> consumer, File file, Long id, SessionUser user) {try (OutputStream os = Files.newOutputStream(file.toPath());) {log.info("开始处理文件....");consumer.accept(os);log.info("处理文件结束....");this.updateStatus(id, Status.PROCESS_DONE, null, user);} catch (Exception e) {log.error("写入文件失败:", e);this.updateStatus(id, Status.PROCESS_FAILED, "写入失败:" + ExceptionUtil.getMessage(e), user);}}/*** (生成文件名用),生成时间戳格式的目录名* @return String*/public static String generateDirPathByTimestamp() {StringBuilder sb = new StringBuilder();Date date = new Date();Long stamp = date.getTime();String formatStamp = String.format("%015d", stamp);for (int i = 0; i < formatStamp.length() / 3; i++) {sb.append("/").append(formatStamp.substring(3 * i, 3 * (i + 1)));}return sb.toString();}

文件状态枚举

//文件状态枚举public enum Status{/****/DEFAULT(0,"未知"),PROCESSING(1,"进行中"),PROCESS_DONE(2,"已完成"),INVALID(3,"已失效"),PROCESS_FAILED(4,"处理失败"),CANCELED(-1,"已取消"),DELETE(-2,"已删除"),;private int code;private String  msg;Status(int code, String msg) {this.code = code;this.msg = msg;}public int getCode() {return code;}public String getMsg() {return msg;}public static Status of(int code){for (Status value : values()) {if (value.getCode() == code){return value;}}return null;}}

使用示例

//收到请求List<List<String>> head;List<List<String>> data;ExecutorService threadPool;doSaveFile("文件导出.xlsx",(os->{EasyExcel.write(os).head(head).doWrite(data);}),threadPool)//返回相应return Result;

其他方式

以上是nas或者直接写入服务器磁盘的方式. 如果是要上传到oss,要么可以先创建在服务器本地,写入流后,再上传到oss然后更新状态为成功. 或者process方法里直接采用oss提供的方式写入
那这样process可以考虑换成Supplier:

      private void process(Supplier<ByteArrayOutputStream> supplier, File file, Long id, SessionUser user) {try (ByteArrayOutputStream  os = supplier.get()) {log.info("开始处理文件....");//输出流写入oss输入流InputStream inputStream = new ByteArrayInputStream(os.toByteArray());log.info("处理文件结束....");this.updateStatus(id, Status.PROCESS_DONE, null, user);} catch (Exception e) {log.error("写入文件失败:", e);this.updateStatus(id, Status.PROCESS_FAILED, "写入失败:" + ExceptionUtil.getMessage(e), user);}}//然后由业务来提供输出流//比如excelByteArrayOutputStream outputStream = (ByteArrayOutputStream) excelWriter.getOutputStream();

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

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

相关文章

重磅福利!参与现金红包抽奖活动,赶快行动吧!

文章目录 粉丝福利 粉丝福利 亲爱的朋友们&#xff0c;令人振奋的消息来啦&#xff01;本月&#xff0c;我们特地为大家准备了一份特别的粉丝福利&#xff01;只要您轻轻一点&#xff0c;关注我们的公众号&#xff0c;就有机会抽取现金红包&#xff0c;让您的生活多一份惊喜与喜…

【微信公众平台】扫码登陆

文章目录 前置准备测试号接口配置 带参数二维码登陆获取access token获取Ticket拼装二维码Url编写接口返回二维码接收扫描带参数二维码事件编写登陆轮训接口测试页面 网页授权二维码登陆生成ticket生成授权地址获取QR码静态文件支持编写获取QR码的接口 接收重定向参数轮训登陆接…

游泳耳机哪个牌子好?体验与口碑兼顾的4大游泳耳机汇总!

最近的天气越来越炎热了&#xff0c;许多人选择游泳作为一种既能锻炼身体又能享受清凉的活动。而随着科技的发展&#xff0c;越来越多的运动爱好者希望在游泳时也能享受到音乐的乐趣。因此&#xff0c;游泳耳机应运而生&#xff0c;成为市场上的热门产品。然而&#xff0c;面对…

使用PixVerse使用指定的角色生成视频

PixVerse 是一款可以将文字描述转换为高清视频的AI视频生成工具&#xff0c;它还支持直接生成原神角色的专属动画视频。以下是如何使用PixVerse使用指定的角色生成视频的步骤&#xff1a; 1. 点击PixVerse 网址 访问以下网址&#xff1a;https://app.pixverse.ai/create/vide…

jvm中的垃圾回收器

Jvm中的垃圾回收器 在jvm中&#xff0c;实现了多种垃圾收集器&#xff0c; 包括&#xff1a; 1.串行垃圾收集器 2.并行垃圾收集器 3.CMS&#xff08;并发&#xff09;垃圾收集器 4.G1垃圾收集器 1.串行垃圾回收器 效率低&#xff0c;使用较少 2.并行垃圾回收器 3.并发垃圾回…

软件估算的方法、过程、内容解读(估算指南)

4 估算方法 4.1 基于经验的方法 4.1.1 头脑风暴法 4.1.2 Delphi方法 4.1.2.1 过程图 4.1.2.2 组建评估组 4.1.2.3 系统介绍 4.1.2.4 系统分解与假设 4.1.2.5 设定偏差值 4.1.2.6 个人估计 4.1.2.7 估计结果汇总 4.1.2.8 估计差异讨论 4.1.2.9 结束 4.2 分解的方法…

Brainpan(VulnHub)

Brainpan 1、nmap 2、web渗透 随便看看 目录爆破 使用不同工具&#xff0c;不同字典进行爆破 9999端口分析 10000端口分析 字符串信息中&#xff0c;提示这个程序不能运行在DOS模式下&#xff0c;然后有32个A&#xff0c;还有一行关于复制字节到缓冲区的信息&#xff0c;还有一…

谈谈前端CSS盒模型

前言&#xff1a; 什么是CSS盒模型&#xff1f;盒模型的构造&#xff1f; 在前端开发中&#xff0c;CSS 盒模型是一种非常基础且核心的概念&#xff0c;它描述了文档中的每个元素被框架处理的方式。 ---- 打开浏览器开发者工具&#xff0c;查看Elements右侧下的Styles底部。 …

libVLC Ubuntu编译详解

1.简介 有时候&#xff0c;windows上开发不满足项目需求&#xff0c;需要移植到linux上&#xff0c;不得不自行编译libvlc&#xff0c;编译libvlc相对而言稍微麻烦一点。 我使用的操作系统&#xff1a;Ubuntu20.04 查看系统命令lsb_release -a libvlc版本&#xff1a; 3.0.1…

elment-plus 中 table 左对齐

elment-plus 中 table 左对齐 <el-tablev-loading"loading"class"flex-1 !h-auto":data"roleList":header-cell-style"{text-align: left }":row-style"{ height: 55px }":cell-style"{ text-align: left }"&…

Argus DBM 一款开源的数据库监控工具,无需部署Agent

开箱即用 无需部署Agent&#xff0c;开箱即用。我们使用JDBC直连您的数据库&#xff0c;输入IP端口账户密码即可。 全平台支持 Argus目前支持对Mysql, PostgreSQL, Oracle等数据库类型的监控&#xff0c;我们也会尽快适配其它数据库&#xff0c;致力于监控所有数据库。我们提…

AES 加解密(包含JS、VUE、JAVA、MySQL)工具方法

介绍 AES 是 Advanced Encryption Standard 的缩写&#xff0c;是最常见的对称加密算法。AES 在密码学中又称 Rijndael 加密法&#xff0c;是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES&#xff0c;已经被多方分析且广为全世界所使用。 基本原理&#…

python 使用 Stable Diffusion API 生成图片示例

python 使用 Stable Diffusion API 生成图片示例 一、前言 在无聊的时候&#xff0c;想瞅一下sd生图遂做了一下 二、具体步骤 1、启动SD的api设置 注意&#xff0c;运行后的api相关功能可以在:http://127.0.0.1:7860/docs 查看 比如这一次我们要的生图的地址就是/sdapi/v1…

华为OD机试 - 结队编程(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

户外旅行摄影手册,旅游摄影完全攻略

一、资料前言 本套旅游摄影资料&#xff0c;大小295.47M&#xff0c;共有9个文件。 二、资料目录 《川藏线旅游摄影》杨桦.彩印版.pdf 《户外摄影指南》(Essential.Guide.to.Outdoor.photography.amateur)影印版.pdf 《旅行摄影大师班》(英)科尼什.扫描版.PDF 《旅行摄影…

数据结构面试常见问题:数组和链表的区别是什么?

数组 在编程的世界里&#xff0c;数组无疑是最基础的数据结构之一&#xff0c;它像一排整齐的房子&#xff0c;每个房子都有自己的门牌号&#xff0c;我们可以通过这个门牌号直接找到这个房子&#xff0c;无需从头至尾的逐一查找。这个门牌号&#xff0c;就是我们所说的索引&am…

一键下载全自动安装Office全家桶

概述 今天分享一款超级强大的工具软件&#xff0c;该软件实现了一键自动化下载、安装Office全家桶的功能。整套安装流程堪称行云流水&#xff0c;从下载到安装全自动&#xff0c;无需上手操作。只需要安装该工具软件后&#xff0c;点击安装即可。软件会自动识别不同的操作系统架…

Oracle——领先的企业级数据库解决方案

一、WHAT IS ORACLWE&#xff1a; ORACLE 数据库系统是美国 ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或B/S 体系结构的数据库之一&#xff0c;ORACLE 通常应用于大型系统的数…

【计算机毕业设计】微信小程序:MHK自学平台的设计与实现——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

MajorDoMo thumb.php 未授权RCE漏洞复现(CNVD-2024-02175)

0x01 产品简介 MajorDoMo是MajorDoMo社区的一个开源DIY智能家居自动化平台。 0x02 漏洞概述 MajorDoMo /modules/thumb/thumb.php接口处存在远程命令执行漏洞&#xff0c;未经身份验证的攻击者可利用此漏洞执行任意指令&#xff0c;获取服务器权限。 0x03 影响范围 MajorD…