SpringBoot+vue 大文件分片下载
学习链接
SpringBoot+vue文件上传&下载&预览&大文件分片上传&文件上传进度
Blob & File & FileReader & ArrayBuffer
Vue+SpringBoot实现文件的分片下载
video标签学习 & xgplayer视频播放器分段播放mp4(Range请求交互过程可以参考这个里面的截图)
【java】java实现大文件的分片上传与下载(springboot+vue3)(代码已fork至本地)
代码
FileController
这里面的代码实现,完全可以参考ResourceHttpRequestHandler#handleRequest
@RestController
public class FileController {private static final int BUFFER_SIZE = 4 * 1024;@RequestMapping(path = "chunkdownload", method = {RequestMethod.HEAD, RequestMethod.POST})public void chunkdownload(HttpServletRequest request, HttpServletResponse response) throws Exception {File file = new File("D:/usr/test/demo.mp4");// 文件总大小long fileSize = file.length();// 设置 Content-Type 和 相关响应头// (这里分片下载响应头设置, 其实可以参考ResourceHttpRequestHandler#handleRequest,// 和 video标签学习 & xgplayer视频播放器分段播放mp4 - https://blog.csdn.net/qq_16992475/article/details/130945997)response.setContentType("application/octect-stream;charset=UTF-8");response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");response.setHeader("Accept-Ranges", "bytes");// 检查请求头中是否有Range请求头,// (可参考:video标签学习 & xgplayer视频播放器分段播放mp4 - https://blog.csdn.net/qq_16992475/article/details/130945997)String rangeHeader = request.getHeader("Range");// 没有Range请求头, 则下载整个文件if (rangeHeader == null) {response.setHeader("Content-Length", String.valueOf(fileSize));InputStream in = new FileInputStream(file);OutputStream out = response.getOutputStream();// 字节缓冲数组byte[] buffer = new byte[BUFFER_SIZE];int bytesRead = -1;// 读取多少, 写多少, 直到读取完毕为止while ((bytesRead = in.read(buffer)) != -1) {out.write(buffer, 0, bytesRead);}in.close();out.close();} else {// 分片下载// (可参考: 参考ResourceHttpRequestHandler#handleRequest中的做法)// 开始索引long start = 0;// 结束索引long end = fileSize - 1;// 获取Range请求头的范围, 格式为:Range: bytes=0-8055,// (其中可能没有结束位置, 若没有位置, 取文件大小-1)String[] range = rangeHeader.split("=")[1].split("-");// 如果Range请求头中没有结束位置, 取文件大小-1if (range.length == 1) {start = Long.parseLong(range[0]);end = fileSize - 1;} else {// 解析开始位置 和 结束位置start = Long.parseLong(range[0]);end = Long.parseLong(range[1]);}// 此次要写出的数据long contentLength = end - start + 1;// 返回头里存放每次读取的开始和结束字节response.setHeader("Content-Length", String.valueOf(contentLength));// 响应状态码206response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);// Content-Range响应头格式为:Content-Range: bytes 0-8055/9000response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileSize);InputStream in = new FileInputStream(file);OutputStream out = response.getOutputStream();// 跳到第start字节in.skip(start);// 字节缓冲数组byte[] buffer = new byte[BUFFER_SIZE];// 读取的字节数量int bytesRead = -1;// 写出的字节数量long bytesWritten = 0;while ((bytesRead = in.read(buffer)) != -1) {// 如果 已写入的数据 + 当前已读到的数据 超过了 此次要写出的数据, 则只能写入请求范围内的数据if (bytesWritten + bytesRead > contentLength) {out.write(buffer, 0, (int) (contentLength - bytesWritten));break;} else {out.write(buffer, 0, bytesRead);bytesWritten += bytesRead;}}in.close();out.close();}}}
ChunkDownload.vue
- 先发1个head请求,获取到文件的大小
- 再发post请求,获取每个分片(其中为了简单理解,就不引入async-await的使用了)
- 将获取的每个分片组合为单个文件
<template><div class="gap"><el-button @click="downloadChunks">分片下载demo.mp4</el-button></div>
</template><script>
import axios from 'axios'export default {name: 'ChunkDownload',components: {},methods: {downloadChunks() {const chunkdownloadUrl = 'http://localhost:8085/chunkdownload'// 分片下载大小 5MBconst chunkSize = 1024 * 1024 * 5;// 文件总大小(需要请求后端获得)let fileSize = 0;axios.head(chunkdownloadUrl).then(res => {// 定义 存储所有的分片的数组let chunks = [];// 获取文件总大小fileSize = res.headers['content-length']// 计算分片数量const chunksNum = Math.ceil(fileSize / chunkSize)// 定义下载文件分片的方法function downloadChunkFile(chunkIdx) {if (chunkIdx >= chunksNum) {alert('分片索引不可超过分片数量')return}let start = chunkIdx * chunkSizelet end = Math.min(start + chunkSize - 1, fileSize - 1)const range = `bytes=${start}-${end}`;axios({url: chunkdownloadUrl,method: 'post',headers: {Range: range},responseType: 'arraybuffer'}).then(response => {chunks.push(response.data)if(chunkIdx == chunksNum - 1) {// 下载好了console.log(chunks, 'chunks');// 组合chunks到单个文件const blob = new Blob(chunks);console.log(blob, 'blob');const link = document.createElement('a');link.href = window.URL.createObjectURL(blob);link.download = 'demo.mp4';link.click();return} else {++chunkIdxdownloadChunkFile(chunkIdx)}})}downloadChunkFile(0)})}}
}
</script><style>
.gap {padding: 10px;
}
</style>
测试

相关文章:
SpringBoot+vue 大文件分片下载
学习链接 SpringBootvue文件上传&下载&预览&大文件分片上传&文件上传进度 Blob & File & FileReader & ArrayBuffer VueSpringBoot实现文件的分片下载 video标签学习 & xgplayer视频播放器分段播放mp4(Range请求交互过程可以参…...
scanf函数读取数据 清空缓冲区
scanf函数读取数据&清空缓冲区 scanf 从输入缓冲区读取数据数据的接收数据存入缓冲区scanf 中%d读取数据scanf中%c读取数据 清空输入缓冲区例子用getchar()吸收回车练习 scanf 从输入缓冲区读取数据 首先,要清楚的是,scanf在读取数据的时候ÿ…...
js 文件常用转换
获取上传文件的arrayBuffer:var u8arr await file.arrayBuffer() 通过arrayBuffer转换成Buffer:Buffer.from(u8arr) 1. Blob、File → Base64 function fileToDataURL(file) {let reader new FileReader();reader.readAsDataURL(file);reader.onload…...
基于Open3D的点云处理15-特征点
Intrinsic shape signatures (ISS) 参考 ISS关键点: 基本原理是避免在沿主要方向表现出类似分布的点上检测关键点,在这些点上无法建立可重复的规范参考框架,因此后续描述阶段很难变得有效。在剩余点中,显着性由最小特征值的大小决定,以便仅包…...
算法刷题Day 58 每日温度+下一个更大元素I
Day 58 单调栈 739. 每日温度 class Solution { public:vector<int> dailyTemperatures(vector<int>& temperatures) {vector<int> rst(temperatures.size());vector<int> decsStk; // 单调递减栈for (int i 0; i < temperatures.size(); i)…...
认识 spring AOP (面向切面编程) - springboot
前言 本篇介绍什么是spring AOP, AOP的优点,使用场景,spring AOP的组成,简单实现AOP 并 了解它的通知;如有错误,请在评论区指正,让我们一起交流,共同进步! 文章目录 前言1. 什么是s…...
将css文件中的px转化为rem
pxToRem.js /*** 使用方式:* 与引入的文件放在同一目录下进行引用配置,执行:node (定义的文件)*/ const fs require(fs) const path require(path) /*** entry:入口文件路径 type:Strng* pxtopx:以倍数转…...
JNI之Java实现远程打印
打印机是最常见的办公设备了。一般情况下如果需要实现打印,可通过前端print.js包来完成。但是,如果要实现智能办公打印,就可以使用JNI技术、封装接口、远程调用实现完成。 导包 jacob:Java COM Bridge <dependency><g…...
YOLOv5基础知识入门(2)— YOLOv5核心基础知识讲解
前言:Hello大家好,我是小哥谈。YOLOV4出现之后不久,YOLOv5横空出世。YOLOv5在YOLOv4算法的基础上做了进一步的改进,使检测性能得到更进一步的提升。YOLOv5算法作为目前工业界使用的最普遍的检测算法,存在着很多可以学习…...
免费的scrum敏捷开发管理工具
Scrum中非常强调公开、透明、直接有效的沟通,这也是“可视化的管理工具”在敏捷开发中如此重要的原因之一。通过“可视化的管理工具”让所有人直观的看到需求,故事,任务之间的流转状态,可以使团队成员更加快速适应敏捷开发流程。 …...
Hive创建外部表详细步骤
① 在hive中执行HDFS命令:创建/data目录 hive命令终端输入: hive> dfs -mkdir -p /data; 或者在linux命令终端输入: hdfs dfs -mkdir -p /data; ② 在hive中执行HDFS命令:上传/emp.txt至HDFS的data目录下,并命名为…...
leetcode 452. 用最少数量的箭引爆气球
2023.8.2 本题思路先将二维数组points按照第一个维度排序, 然后初始化射箭数为1,因为题中提示说了最少有一个气球。 在遍历这些气球,看是否有重叠,如果没有重叠区域,射箭数;如果有重叠区域,更新…...
Pytorch Tutorial【Chapter 3. Simple Neural Network】
Pytorch Tutorial【Chapter 3. Simple Neural Network】 文章目录 Pytorch Tutorial【Chapter 3. Simple Neural Network】Chapter 3. Simple Neural Network3.1 Train Neural Network Procedure训练神经网络流程3.2 Build Neural Network Procedure 搭建神经网络3.3 Use Loss …...
2.虚拟机开启kali_linux
首先你应该搞一个虚拟机,搞虚拟机可以看一下这个 附录三 虚拟机的使用_Suyuoa的博客-CSDN博客 然后你需要搞一个 kali linux的镜像 Get Kali | Kali Linux 镜像下载好之后解压,你会得到一个文件夹包含下面这些文件 之后打开VMware,点击打开虚…...
【StyleGAN2论文精读CVPR_2020】Analyzing and Improving the Image Quality of StyleGAN
【StyleGAN2论文精读CVPR_2020】Analyzing and Improving the Image Quality of StyleGAN 一、前言Abstract1. Introduction2. Removing normalization artifacts2.1. Generator architecture revisited2.2. Instance normalization revisited 3. Image quality and generator …...
医学图像处理
医学图像处理 opencv批量分片高像素图像病理图像色彩特征提取病理图像细微特征提取自动数据标注分类场景下的医学图像分析分割场景下的医学图像分析检测场景下的医学图像分析 , i ] k 8 < * I opencv批量分片高像素图像 医学图像通常是大像素(1920x1080&…...
PyCharm安装使用2023年教程,PyCharm与现流行所有编辑器对比。
与PyCharm类似的功能和特性的集成开发环境(IDE)和代码编辑器有以下几种: Visual Studio Code(VS Code):由Microsoft开发,VS Code是一个高度可定制和可扩展的代码编辑器。它支持多种编程语言&am…...
vue3中CompositionApi理解与使用
CompositionApi,组合式API,相当于react中hooks,函数式。 优势:1,增加了代码的复用性(类似mixin,slot,高阶组件功能) 2,代码可读性更好。可以将处理逻辑和视图…...
【前瞻】视频技术的发展趋势讨论以及应用场景
视频技术的发展可以追溯到19世纪初期的早期实验。到20世纪初期,电视技术的发明和普及促进了视频技术的进一步发展。 1)数字化:数字化技术的发明和发展使得视频技术更加先进。数字电视信号具有更高的清晰度和更大的带宽,可以更快地…...
Visual Studio在Debug模式下,MFC工程中包含Eigen库时的定义冲突的问题
Visual Studio在Debug模式下,MFC工程中包含Eigen库时的定义冲突的问题 报错信息 Eigen\src\Core\PlainObjectBase.h(143,5): error C2061: 语法错误: 标识符“THIS_FILE” Eigen\src\Core\PlainObjectBase.h(143,1): error C2333: “Eigen::PlainObjectBase::opera…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
