Vue中实现大文件的切片并发下载和下载进度展示

Vue中实现大文件的切片下载

切片下载需要后端提供两个接口,第一个接口用来获取当前下载文件的总切片数,第二个接口用来获取具体某一个切片的内容。

界面展示

在这里插入图片描述

数据流展示

在这里插入图片描述

代码

接口

// 切片下载-获取文件的总切片数
export function getChunkDownloadMetaInfo(queryParams) {
  return request({
    url: `/resource/chunkDownloadMetaInfoByUrl`,
    method: 'get',
    params: queryParams
  })
}

// 切片下载-获取当前切片的文件内容
export function getChunkDownload(queryParams) {
  return request({
    url: `/resource/chunkDownloadByUrl`,
    method: 'get',
    headers: {
      'Content-Type': 'application/json; application/octet-stream'
    },
    responseType: 'blob', //响应数据格式配置
    params: queryParams
  })
}

下载

// 下载
const downloadItem = async item => {
  const fileName = item.fileName
  const fileUrl = item.fileUrl
  if (item.isDownloading) {
    ElMessage({
      type: 'error',
      message: `${fileName}正在下载中请稍等`
    })
    return
  }
  item.progress = 0 // 下载进度
  item.isDownloading = true // 是否正在下载
  item.isAborted = false // 是否中止下载
  try {
    // 获取文件信息
    const fileInfo = await getFileInfo(fileUrl)
    const totalChunks = fileInfo.totalChunkNum

    // 并发下载所有切片
    const downloadedChunks = await downloadWithConcurrency(fileUrl, fileName, totalChunks, item)

    // 合并并下载文件
    const mergedBlob = mergeBlobs(downloadedChunks)
    triggerDownload(mergedBlob, fileName)
  } catch (error) {
    console.error('下载失败:', error)
    ElMessage({
      type: 'error',
      message: `${fileName}文件下载失败`
    })
  } finally {
    item.isDownloading = false
  }
}
// 获取文件信息
const getFileInfo = async fileUrl => {
  try {
    const response = await getChunkDownloadMetaInfo({ url: fileUrl })
    return response.data
  } catch (error) {
    throw new Error(`获取文件信息失败: ${error.message}`)
  }
}
// 下载单个切片
const downloadChunk = async (fileUrl, fileName, chunkIndex) => {
  try {
    const response = await getChunkDownload({
      url: fileUrl,
      chunkNumber: chunkIndex
    })
    return response
  } catch (error) {
    throw new Error(`下载切片失败: ${error.message}`)
  }
}
// 合并 Blob
const mergeBlobs = blobs => {
  return new Blob(blobs)
}
// 触发文件下载
const triggerDownload = (blob, fileName) => {
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = fileName
  a.click()
  URL.revokeObjectURL(url)
}
// 并发下载
const downloadWithConcurrency = async (fileUrl, fileName, totalChunks, item) => {
  const downloadedChunks = new Array(totalChunks).fill(null)
  let completedChunks = 0

  const downloadNextChunk = async chunkIndex => {
    if (item.isAborted) return // 如果已中止,直接返回

    try {
      const chunk = await downloadChunk(fileUrl, fileName, chunkIndex)
      console.log(chunk, '123123123123123123')
      downloadedChunks[chunkIndex] = chunk

      // 更新下载进度
      completedChunks++
      item.progress = Math.round((completedChunks / totalChunks) * 100)
    } catch (error) {
      item.isAborted = true // 中止下载
      throw error
    }
  }

  // 启动并发下载
  const workers = []
  for (let i = 0; i < totalChunks; i++) {
    if (item.isAborted) break // 如果已中止,停止启动新任务

    if (workers.length >= maxConcurrency) {
      // 等待一个任务完成后再启动新任务
      await Promise.race(workers)
    }

    const worker = downloadNextChunk(i).finally(() => {
      workers.splice(workers.indexOf(worker), 1)
    })
    workers.push(worker)
  }

  await Promise.all(workers) // 等待所有任务完成
  return downloadedChunks
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hive-数据倾斜优化

数据倾斜的原因 1&#xff09;key分布不均匀&#xff0c;本质上就是业务数据有可能会存在倾斜 2&#xff09;某些SQL语句本身就有数据倾斜 关键词 情形 后果 Join A、其中一个表较小&#xff0c;但是key集中; B、两张表都是大表&#xff0c;key不均 分发到…

java通过lombok自动生成getter/setter方法、无参构造器、toString方法

文章目录 在IDEA打开允许注解在类名上面使用Data注解 在IDEA打开允许注解 打开设置 在类名上面使用Data注解 按住AltEnter键 等依赖下载完成后上面会新增一行import lombok.Data; 完整代码如下&#xff1a; package com.itheima.extendss;import lombok.AllArgsConstru…

RabbitMQ 2025/3/5

高性能异步通信组件。 同步调用 以支付为例&#xff1a; 可见容易发生雪崩。 异步调用 以支付为例&#xff1a; 支付服务当甩手掌柜了&#xff0c;不管后面的几个服务的结果。只管库库发&#xff0c;后面那几个服务想取的时候就取&#xff0c;因为消息代理里可以一直装&#x…

Element UI-Select选择器结合树形控件终极版

Element UI Select选择器控件结合树形控件实现单选和多选&#xff0c;并且通过v-model的方式实现节点的双向绑定&#xff0c;封装成vue组件&#xff0c;文件名为electricity-meter-tree.vue&#xff0c;其代码如下&#xff1a; <template><div><el-select:valu…

9.RabbitMQ消息的可靠性

九、消息的可靠性 1、生产者确认 9.1.1、Confirm模式简介 可能因为网络或者Broker的问题导致①失败,而此时应该让生产者知道消息是否正确发送到了Broker的exchange中&#xff1b; 有两种解决方案&#xff1a; 第一种是开启Confirm(确认)模式&#xff1b;(异步) 第二种是开…

探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(二)

文章目录 2.3.3 极化编码巴氏参数与信道可靠性比特混合生成矩阵编码举例 2.3.4 极化译码最小单元译码串行抵消译码&#xff08;SC译码&#xff09;算法SCL译码算法 2.3.5 总结**Polar 码的优势****Polar 码的主要问题****Polar 码的应用前景** 2.3.6 **参考文档** 本博客为系列…

【我的 PWN 学习手札】House of Emma

House of Emma 参考文献 第七届“湖湘杯” House _OF _Emma | 设计思路与解析-安全KER - 安全资讯平台 文章 - house of emma 心得体会 - 先知社区 前一篇博客【我的 PWN 学习手札】House of Kiwi-CSDN博客的利用手法有两个关键点&#xff0c;其一是利用__malloc_assert进入…

【单片机通信技术】STM32 HAL库 SPI主从机通过串口发送数据

一、说明 使用STM32F103C8T6最小系统板&#xff0c;让板载SPI1与SPI2通信&#xff0c;通过串口收发数据。本文章说明了在配置与编写时遇到的一些问题&#xff0c;以及详细说明如何使用cubeMAX进行代码编写。 二、CubeMAX配置 1.时钟配置选择外部高速时钟 2.系统模式与时钟配…

IDEA 使用codeGPT+deepseek

一、环境准备 1、IDEA 版本要求 安装之前确保 IDEA 处于 2023.x 及以上的较新版本。 2、Python 环境 安装 Python 3.8 或更高版本 为了确保 DeepSeek 助手能够顺利运行&#xff0c;您需要在操作系统中预先配置 Python 环境。具体来说&#xff0c;您需要安装 Python 3.8 或更高…

Vue 3 实现富文本内容导出 Word 文档:前端直出方案与优化实践

本文将深入讲解如何通过纯前端方案将富文本内容直接导出为符合中文排版规范的 Word 文档&#xff0c;对比传统服务端生成方案&#xff0c;本方案可降低服务器压力 80% 以上&#xff0c;同时支持即时下载功能。 一、功能全景图 该方案实现以下核心能力&#xff1a; ✅ 纯前端 W…

数据可视化设计-FineBI

数据可视化设计-FineBI 5.1 FineBI概述 5.1.1 FineBI简介 FineBI 是帆软软件有限公司推出的一款商业智能&#xff08;Business Intelligence&#xff09;产品。 FineBI 是新一代大数据分析的 BI 工具&#xff0c;旨在帮助企业的业务人员充分了解和利用他们的数据。FineBI 凭…

一篇文章讲解清楚ARM9芯片启动流程

SAM9X60 ARM9 boot启动流程关键词介绍&#xff1a; 第一级bootloader - 也叫boot ROM&#xff0c;是集成在MPU内部的ROM里面 它的主要功能是执行对MPU的基本初始化和配置&#xff0c;查找并将第二级bootloader从外部NVM中读取出来并放到MPU内部的SRAM. 可以让MPU强制停留在第一…

【JavaSE-6】数组的定义与使用

1、数组的基本概念 1.1、为什么使用数组 为了方便将同一种数据类型的数据进行存储。 1.2、什么是数组 指的是一种容器&#xff0c;可以同来存储同种数据类型的多个值。但是数组容器在存储数据的时候&#xff0c;需要结合隐式转换考虑。如&#xff1a;定义一个int类型的数组…

基于eRDMA实测DeepSeek开源的3FS

DeepSeek昨天开源了3FS分布式文件系统, 通过180个存储节点提供了 6.6TiB/s的存储性能, 全面支持大模型的训练和推理的KVCache转存以及向量数据库等能力, 每个客户端节点支持40GB/s峰值吞吐用于KVCache查找. 发布后, 我们在阿里云ECS上进行了快速的复现, 并进行了性能测试, ECS…

Linux网络编程(20250301)

网络通信&#xff1a;进行不同主机的进程间通信 解决硬件与软件的互联互通 主机-->交换机-->路由器-->广域网-->路由器-->交换机-->主机 IP地址&#xff1a;区分不同主机 MAC地址&#xff1a;计算机硬件地址 端口号&#xff1a;区分主机上的不同进程 1…

JAVA安全—手搓内存马

前言 最近在学这个内存马&#xff0c;就做一个记录&#xff0c;说实话这个内存马还是有点难度的。 什么是内存马 首先什么是内存马呢&#xff0c;顾名思义就是把木马打进内存中。传统的webshell一旦把文件删除就断开连接了&#xff0c;而Java内存马则不同&#xff0c;它将恶…

HarmonyOS学习第11天:布局秘籍RelativeLayout进阶之路

布局基础&#xff1a;RelativeLayout 初印象 在 HarmonyOS 的界面开发中&#xff0c;布局是构建用户界面的关键环节&#xff0c;它决定了各个组件在屏幕上的位置和排列方式。而 RelativeLayout&#xff08;相对布局&#xff09;则是其中一种功能强大且灵活的布局方式&#xff0…

【Bootstrap5】Bootstrap5学习笔记

目的 学完Blazor以后&#xff0c;我自己用这个写了一个小工具&#xff0c;但是我发现自己对前端粗浅的认知确实很难把UI层的组件弄出我想要的样子&#xff0c;所以我思来想去决定再把前端知识补一补.记录基于菜鸟教程的Bootstrap5教程&#xff0c;然后有些不清楚的我还补充一些…

【JMeter】JMeter之MQTT压测

文章目录 MQTT概念Jmeter压测MQTTMQTT服务器下载Jmeter MQTT插件测试MQTT测试思路和解决方法 MQTT概念 MQTT是什么 MQTT是用于物联网&#xff08;IoT&#xff09;的OASIS标准消息传递协议。它被设计为一种非常轻量级的发布/订阅消息传输&#xff0c;非常适合使用较少的代码占用…

Android U 分屏——SystemUI侧处理

WMShell相关的dump命令 手机分屏启动应用后运行命令&#xff1a;adb shell dumpsys activity service SystemUIService WMShell 我们可以找到其中分屏的部分&#xff0c;如下图所示&#xff1a; 分屏的组成 简图 分屏是由上分屏(SideStage)、下分屏(MainStage)以及分割线组…