分片上传技术全解析:原理、优势与应用(含简单实现源码)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~


作者:watermelo617

涉及领域:Vue、SpingBoot、Docker、LLM、python

-------------------------------------------------------------------------------------------------------------------------

--------------------------温柔地对待温柔的人,包容的三观就是最大的温柔。--------------------------

-------------------------------------------------------------------------------------------------------------------------

image.gif 编辑

分片上传技术全解析:原理、优势与应用(含简单实现源码)

一、什么是分片上传

       分片上传(Chunked Upload)是将大文件分成多个较小的部分(分片)来逐个上传到服务器。上传完成后,服务器将这些分片重新组装成原始文件。这个过程通常包括以下几个步骤:

  1. 分片:文件被切割成多个小的片段,每个片段的大小通常是预定义的。
  2. 上传:每个分片被单独上传到服务器。上传过程中,通常会附带分片的索引和其他元数据。
  3. 组装:服务器接收到所有分片后,将它们按正确的顺序重新组装成完整的文件。
  4. 确认:完成组装后,服务器可以返回一个确认响应,表示文件上传成功。

image.gif 编辑

二、分片上传解决了什么问题

       分片上传是一个有效的处理大文件上传问题的方案,它通过将文件分割为小片段来提高上传的可靠性和效率,并确保数据的完整性。在网络环境环境不好,存在需要重传风险的场景,分片上传能有效提升上传的体验。

       其具体优势在于:

  1. 大文件上传的稳定性:对于大文件,直接上传可能会因为网络问题、超时等导致上传失败。分片上传可以在单个分片上传失败时仅重新上传失败的分片,而不是整个文件,提高了上传的成功率。
  2. 减少内存使用:分片上传可以将大文件拆分为较小的片段,这样可以减少内存消耗并优化上传性能。
  3. 断点续传:分片上传支持断点续传。即使上传过程中发生了中断,用户可以从中断的位置继续上传,不必从头开始。
  4. 负载均衡:可以在多个服务器之间分配分片上传任务,提高系统的负载均衡能力。

三、分片上传的本质

3.1、分片上传的本质意义

       分片上传的本质就是将大文件分割成多个较小的部分,逐个上传到服务器,然后在服务器端将这些部分重新组合成完整的文件。这种方法不仅解决了大文件上传的问题,还能优化网络带宽和提高上传效率。

       大多数情况下,服务器会负责将接收到的分片重新组装成完整的文件。服务器通常会根据分片的索引顺序将它们拼接起来。在某些情况下,客户端可能会将所有分片上传到服务器后,由客户端自行处理合并操作(通常较少见)。

3.2、分片上传的风险与规避方式

①网络问题

       网络中断可能导致某些分片上传失败。为了应对这种情况,可以实现重试机制和断点续传功能。

②服务器端错误

       服务器在接收和组装分片时可能会发生错误。应确保服务器有适当的错误处理和日志记录机制。

③文件完整性校验

       为了确保文件在上传和组装过程中没有发生损坏,通常会计算文件的哈希值,并在上传完成后进行校验。在第四部分案例代码中使用了SparkMD5来计算文件的MD5哈希值,以确保文件的一致性和完整性。

3.3、分片上传中的重试机制与断点续传

       这些技术可以结合使用,以提高上传的鲁棒性。重试机制确保分片上传的稳定性,断点续传支持上传中断后的恢复。

①重试机制

       重试机制是在上传过程中,如果遇到网络问题、服务器错误或其他上传失败的情况,自动重新尝试上传失败的部分(通常是分片上传中会使用重试机制)。适用于网络不稳定或服务器偶尔出现故障的情况。可以做到:

  • 提高成功率:自动处理上传失败的情况,提高上传成功率。
  • 错误恢复:在上传过程中遇到错误时,可以自动恢复,无需用户干预。
  • 可配置性:重试次数和时间间隔可以进行配置,以适应不同的需求和网络环境。

②断点续传

       断点续传断点续传是允许在上传过程中中断后,能够从中断的位置继续上传,而不是从头开始。这通常涉及记录已上传的部分,并在恢复时跳过这些已上传部分。

       一般来说,断点续传是从断开的分片起,重新上传该分片及之后的分片。但也有更精细的实现方式,从精确的分片的断点位置起,这样在中断频繁的网络环境中表现更好,可以避免重复上传已经部分成功的内容。更加高效和灵活,但实现复杂度较高。

       断点续传有助于:

  • 中断恢复:在上传过程中,如果发生中断,可以从中断点继续上传,而不是重新上传整个文件。
  • 记录状态:需要在客户端或服务器端记录上传进度。
  • 用户体验:提升用户体验,避免长时间上传过程中的中断带来的困扰。

四、基于js的简单实现案例

       前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="upload" type="file" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/3.0.2/spark-md5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.2/axios.min.js"></script>
    <script>
        // 如何获取input,监听上传事件
        var inputs = document.getElementById('upload')
        inputs.onchange = async () => {
            // console.log(inputs.files, 'file')
            // 获取到上传的文件对象
            var file = inputs.files[0]
            // 创建分片数据
            var chunks = createChunk(file, 50 * 1024 *1024)
           
            // 文件内容创建hash
            var res = await hash(chunks)
            console.log(res, 'hash')
            // 调用发送分片的接口
            uploadChunk(chunks, res, file.name)
        }
        // 创建分片
        function createChunk(file, chunkSize) {
            const result = []
            for (let i = 0; i < file.size; i += chunkSize) {
                result.push(file.slice(i, i + chunkSize))
            }
            return result
        }
        // 根据文件内容创建hash值
        function hash(chunks) {
            return new Promise((resolve) => {
                var spark = new SparkMD5()
                // 递归
                function _read(i) {
                    if (i >= chunks.length) {
                        resolve(spark.end())
                        return
                    }
                    // 获取当前其中的一个片段
                    var blob = chunks[i]
                    // 创建一个FileReader对象
                    var reader = new FileReader()
                    reader.onload = e => {
                    var bytes = e.target.result
                    spark.append(bytes)
                    _read(i + 1)
                    }
                    reader.readAsArrayBuffer(blob)
                }
                _read(0)
            })
        }
        // 分片上传
        function uploadChunk(chunks, hash, fileName) {
            // 文件怎么样传给后端? ok
            // 所有分片上传成功后,有一个通知告诉后端已经上传完成?
            var taskArr = []
            chunks.forEach((chunk, index) => {
                var formdata = new FormData()
                formdata.append('chunk', chunk)
                formdata.append('chunkName', `${hash}-${index}-${fileName}`)
                formdata.append('fileName', fileName)
                var task = axios.post('http://127.0.0.1:3000/upload', formdata, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                })
                taskArr.push(task)
            });
            Promise.all(taskArr).then(() => {
                // 所有分片上传成功后的结果
                console.log('通知后端')
            })
            
        }
    </script>
</body>
</html>

image.gif

        极简的后端接口(模拟发送请求,不具备实际后端作用):

const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
const hostname = '127.0.0.1'
const port = 3000
app.use(express.json())
// 模拟支付
app.post('/upload', (req, res) => {
  res.status(200).json({})
})
app.listen(port, hostname, () => {
  console.log(`Server is running at http://${hostname}:${port}/`)
})

image.gif

五、总结

       分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。

        博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

       更多优质内容,请关注:

JS语法与Vue开发:

       浏览器渲染揭秘:从加载到显示的全过程

       Vue 性能革命:揭秘前端优化的终极技巧

       属性描述符初探——Vue实现数据劫持的基础

       你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解

       最细最有条理解析:事件循环(消息循环)是什么?进程与线程的定义、关系与差异

       路由通配符,小小的字符有大大的作用,你真的熟悉吗?

       管理数据必备!侦听器watch用法详解

       什么是深拷贝?深拷贝和浅拷贝有什么区别

       对象数据的读取,看这一篇就够了!

       通过array.every()实现数据验证、权限检查和一致性检查,array.some与array.every的区别

       通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理

       通过array.map()实现数据转换、创建派生数组、异步数据流处理、搜索和过滤等需求

       通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式等

       通过array.filter()实现数组的数据筛选、数据清洗和链式调用

       多维数组操作,不要再用遍历循环foreach了,来试试数组展平的小妙招!

       别再用双层遍历循环来做新旧数组对比,寻找新增元素了!

       shpfile转GeoJSON且控制转化精度;如何获取GeoJSON?GeoJson结构详解

       Mapbox添加行政区矢量图层、分级设色图层、自定义鼠标悬浮框、添加天地图底图等

Element plus拓展:

       通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称等

       el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能

       el-table中如何添加渐变色带、多色色带

优质前端组件库:

       高效工作流:用Mermaid绘制你的专属流程图

相关文章
|
24天前
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
|
1月前
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
94 27
|
1月前
|
存储 弹性计算 安全
阿里云服务器ECS通用型规格族解析:实例规格、性能基准与场景化应用指南
作为ECS产品矩阵中的核心序列,通用型规格族以均衡的计算、内存、网络和存储性能著称,覆盖从基础应用到高性能计算的广泛场景。通用型规格族属于独享型云服务器,实例采用固定CPU调度模式,实例的每个CPU绑定到一个物理CPU超线程,实例间无CPU资源争抢,实例计算性能稳定且有严格的SLA保证,在性能上会更加稳定,高负载情况下也不会出现资源争夺现象。本文将深度解析阿里云ECS通用型规格族的技术架构、实例规格特性、最新价格政策及典型应用场景,为云计算选型提供参考。
|
1月前
|
数据采集 机器学习/深度学习 存储
可穿戴设备如何重塑医疗健康:技术解析与应用实战
可穿戴设备如何重塑医疗健康:技术解析与应用实战
77 4
|
1月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
166 29
|
5月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
167 2
|
1月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
59 3
|
1月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。
|
1月前
|
存储 前端开发 JavaScript
在线教育网课系统源码开发指南:功能设计与技术实现深度解析
在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。

推荐镜像

更多
下一篇
oss创建bucket