当前位置: 首页 > article >正文

文件分片上传 python

服务端功能

上传分片保存

@app.route('/upload_filesliceprocess', methods=['POST'])
def upload_filesliceprocess():
    file = request.files['file']
    name_index = request.form['name_index']
    complete = request.form['complete']
    process = request.form['process']
    clienthash = request.form['clienthash']

    source_name = request.form['filename']
    filename = ''.join(source_name.split('.')[0:-1])
    file_path = fr'{SLICE_DATA}/{filename}'
    p_file_path = pd.Path(file_path)
    if not pd.Path.exists(p_file_path):
        os.makedirs(p_file_path)
    fileindex=fr'{file_path}/{name_index}'
    filename=fr'{file_path}/{name_index}'
    if(os.path.exists(fileindex)==False):
       
        file.save(filename)
    import utils
    
    hashserver=utils.calculate_md5(filename)
    if(clienthash==hashserver):
        return 'ok'
    else:
       return 'error'

    print(f'process:{round(float(process)*100, 2)}%')

合并分片功能

@app.route('/merge_file', methods=['POST'])
def merge_file():
    print('-------------------------------')
     
    filename = request.form['filename']
    print(filename)
    #splitfile=os.path.splitext(filename)
   
    #filename=splitfile[0]
   
    #ext=splitfile[1]
    filename, ext = os.path.splitext(filename)
    ext=ext.replace('.','')
    
    file_path= fr'{SLICE_DATA}/{filename}'
    combination_fun(file_path,filename,ext)
    return 'ok'

合并文件函数

def combination_fun(folder_path, source_name,ext):

    com_path = pd.Path(COMBINATION_DATA)
    if not pd.Path.exists(com_path):
        os.makedirs(com_path)

    ready_folder = os.listdir(folder_path)
    ready_sort_folder = sorted(ready_folder, key=lambda x: int(x.split('_')[-1]))
    with open(f'{COMBINATION_DATA}/{source_name}.{ext}', 'wb') as write_f:
        for item in ready_sort_folder:
            slice_item = os.path.join(folder_path, item)
            print(slice_item)
            with open(slice_item, "rb") as read_f:
                content = read_f.read()
                write_f.write(content)
    #删除缓存文件
    for item in ready_sort_folder:
            slice_item = os.path.join(folder_path, item)
            os.remove(slice_item)

前端

引用库   jquery Md5

  <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

上传简单界面

   <input type="file" name="file" id="file">
    <button id="upload" onClick="uploadfile()">upload</button>
    <button id="mergedata" onClick="uploadcomplete()">mergedata</button>    
   <div class="rate_div" >
       上传进度:<span id="rate_nums">0</span>
            <progress id="downloadProgress" value="0"  max="100"></progress>
   </div>

上传脚本

<script type="text/javascript">
       
        var totalPieces=0;
    var nowUploadNums = 0;
    const MAX_RETRIES = 5; // 最大重试次数
    const CHUNK_SIZE = 100*1024 * 1024; // 1MB 分片大小
        
    let arr = [];
    let retries=[];
        //发送请求
    function displayProgress(percent) {
           
            
                document.getElementById('downloadProgress').value = percent;
               
         }

    function mergedata()
    {
        var blob = document.getElementById("file").files[0];
          
            var filesize = blob.size;
            var filename = blob.name;

    }
    function setRate(num) {
          var rateNums = document.getElementById('rate_nums');
          rateNums.innerHTML = num;
    }
    function uploadcomplete()
    {
        nowUploadNums ++;
        if(nowUploadNums >=totalPieces)
        {
        console.log('true')
        
                 var blob = document.getElementById("file").files[0];
           
                var filename = blob.name;
         var formData = new FormData();
                
                   formData.append("filename", filename);
                
          $.ajax({
                    url: '/merge_file',
                    type: 'POST',
                    cache: false,
                    data: formData,
        
                    processData: false,
                    contentType: false,
             
                }).done(function(res){
                   alert('合并成功');

                }).fail(function(res) {
            alert('合并失败');
            

                });
                                            
          }
        else{
            console.log('false')
        }
        
    }
        function uploadfile() {
            var blob = document.getElementById("file").files[0];
            var start = 0;
            var end;
            var index = 1;
            var filesize = blob.size;
            var filename = blob.name;
            var complete = false;
        nowUploadNums =0;
        const  totalChunks= Math.ceil(filesize / CHUNK_SIZE );
            let uploadedChunks = 0;
            let chunkRetries = {};
          function updateProgress() {
            
        document.getElementById('downloadProgress').value =Math.round((uploadedChunks / totalChunks) * 100);

          
           }

        function uploadNextChunk() {
            if (uploadedChunks >= totalChunks) {
                console.log('文件上传完成!');
                updateProgress(); // 确保进度条显示100%
                // 通知服务器所有分片都已上传,可以进行合并
                return;
            }

            const start = uploadedChunks * CHUNK_SIZE;
            const end = Math.min(start + CHUNK_SIZE, blob.size);
            const chunk = blob.slice(start, end);
            const chunkIndex = uploadedChunks;

            if (!chunkRetries[chunkIndex]) {
                chunkRetries[chunkIndex] = 0;
            }
         
       const wordArray = CryptoJS.lib.WordArray.create(chunk );
              const clienthash= CryptoJS.MD5(wordArray).toString()
            uploadChunk(chunk, chunkIndex,filename ,clienthash,complete,uploadedChunks , totalChunks).then(() => {
                uploadedChunks++;
                updateProgress(); // 更新进度条
                uploadNextChunk(); // 上传下一个分片
            }).catch((error) => {
                chunkRetries[chunkIndex]++;
                console.error(`上传分片 ${chunkIndex} 失败: ${error.message}, 重试次数: ${chunkRetries[chunkIndex]}/${MAX_RETRIES}`);
                if (chunkRetries[chunkIndex] < MAX_RETRIES) {
                    // 等待一段时间后重试上传当前分片
                    setTimeout(uploadNextChunk, 1000); // 延迟1秒重试
                } else {
                    console.error(`分片 ${chunkIndex} 上传失败,已达到最大重试次数`);
                    // 处理上传失败的情况,比如停止上传或通知用户
                }
            });
        
          }
        uploadNextChunk();
    }
           

    
    function uploadChunk(chunk, sliceIndex,filename,clienthash,complete,index,totalPieces) {
          var formData = new FormData();
          formData.append("file", chunk);
          formData.append("name_index", sliceIndex);
          formData.append("filename", filename);
      formData.append("clienthash", clienthash);
          formData.append("complete",complete);
          formData.append("process", index / totalPieces);

        return $.ajax({
            url: '/upload_filesliceprocess', // 替换为你的上传URL
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            // 可以设置timeout来处理请求超时的情况
        });
    }

相关文章:

文件分片上传 python

服务端功能 上传分片保存 app.route(/upload_filesliceprocess, methods[POST]) def upload_filesliceprocess(): file request.files[file] name_index request.form[name_index] complete request.form[complete] process request.form[process] c…...

外汇掉期(FX Swap):全球企业管理外汇风险的关键工具(中英双语)

外汇掉期&#xff08;FX Swap&#xff09;&#xff1a;全球企业管理外汇风险的关键工具 引言 在全球化经济环境下&#xff0c;跨国公司、银行和金融机构经常面临外汇风险&#xff0c;因为它们的业务涉及多种货币。例如&#xff0c;一家中国公司可能需要欧元支付欧洲供应商&am…...

Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件

步骤1 开始通过 WSL 使用 VS Code | Microsoft Learn 点击远程开发扩展包。 步骤2 Remote Development - Visual Studio Marketplace 点击install&#xff0c; 允许打开Visual Studio Code。 步骤3 共有4项&#xff0c;一齐安装。 步骤4 在WSL Linux(Ubuntu)中&#xf…...

网络安全“挂图作战“及其场景

文章目录 一、网络安全挂图作战来源与定义1、网络安全挂图作战的来源2、网络安全挂图作战的定义 二、挂图作战关键技术三、挂图作战与传统态势感知的差异四、挂图作战主要场景五、未来趋势结语 一、网络安全挂图作战来源与定义 1、网络安全挂图作战的来源 网络安全挂图作战的…...

开源在线考试系统开源在线考试系统:支持数学公式的前后端分离解决方案

开源在线考试系统&#xff1a;支持数学公式的前后端分离解决方案 项目介绍项目概述&#xff1a;技术栈&#xff1a;版本要求主要功能&#xff1a;特色亮点 项目仓库地址演示地址GiteeGitHub 系统效果展示教师端系统部分功能截图学生端系统部分功能截图 结语 项目介绍 项目概述…...

解决 ssh connect to host github.com port 22 Connection timed out

一、问题描述 本地 pull/push 推送代码到 github 项目报 22 端口连接超时&#xff0c;测试连接也是 22 端口连接超时 ssh 密钥没问题、也开了 Watt Toolkit 网络是通的&#xff0c;因此可以强制将端口切换为 443 二、解决方案 1、测试连接 ssh -T gitgithub.com意味着无法通…...

分享8款AI生成PPT的工具!含测评

随着人工智能技术的飞速进步&#xff0c;制作PPT变得愈发便捷&#xff0c;仅需输入主题指令&#xff0c;便能在瞬间获得一份完整的演示文稿。尤其在制作篇幅较长的PPT时&#xff0c;手动编写每一页内容并设计格式和排版&#xff0c;不仅效率低下&#xff0c;而且耗时耗力。 本…...

Java 设计模式总结

文章目录 Java 设计模式总结创建型模式&#xff08;5种&#xff09;结构型模式&#xff08;7种&#xff09;行为型模式&#xff08;11种&#xff09; Java 设计模式总结 设计模式&#xff08;Design Patterns&#xff09;是软件工程中解决常见问题的经典解决方案。它们提供了一…...

Spring Boot Actuator 监控✨

Spring Boot Actuator 是 Spring Boot 提供的一个强大的监控和管理工具&#xff0c;它可以帮助你深入了解和监控你的应用程序的运行状态。通过 Actuator&#xff0c;你可以获取应用程序的健康状况、内存使用情况、线程信息、HTTP 请求跟踪等。&#x1f680; 核心知识点 &#…...

解锁原型模式:Java 中的高效对象创建之道

系列文章目录 后续补充~~~ 文章目录 一、引言1.1 软件开发中的对象创建困境1.2 原型模式的登场 二、原型模式的核心概念2.1 定义与概念2.2 工作原理剖析2.3 与其他创建型模式的差异 三、原型模式的结构与角色3.1 抽象原型角色3.2 具体原型角色3.3 客户端角色3.4 原型管理器角色…...

23种设计模式 - 责任链

模式定义 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;允许多个对象按链式顺序处理请求&#xff0c;直到其中一个对象处理为止。该模式将请求的发送者和接收者解耦&#xff0c;使多个对象都有机会处理请求。 模式结构…...

【Linux-命令】

Linux-命令 ■ ls■ cd■ pwd■ tree■ mkdir■ rm■ mv■ cp■ chmod■ chattr 文件的特殊属性■ cat■ 日期■ 关机■ find■ 查看文件内容■ cat■ ln■ mount 挂载一个文件系统■ uname■ 用户和组■ 打包和压缩■ zip■ gzip■ rar■ tar ■ 包■ rpm 包■ yum 软件包升级…...

豪越科技:消防安全重点单位一体化安全管控

在当今数字化高速发展的时代&#xff0c;消防安全的重要性日益凸显。豪越科技以其卓越的技术实力和创新精神&#xff0c;将物联网、大数据、人工智能等先进技术深度融合&#xff0c;打造出了功能强大的消防安全重点单位一体化安全管控平台&#xff0c;为消防安全管理带来了全新…...

LabVIEW无刷电机控制器检测系统

开发了一种基于LabVIEW的无刷电机控制器检测系统。由于无刷电机具有高效率、低能耗等优点&#xff0c;在电动领域有取代传统电机的趋势&#xff0c;而无刷电机的核心部件无刷电机控制器产量也在不断增长。然而&#xff0c;无刷电机控制器的出厂检测仍处于半自动化状态&#xff…...

EXCEL解决IF函数“您已为此函数输入太多个参数”的报错

IF函数的基本结构是IF(条件, 值为真时的结果, 值为假时的结果)&#xff0c;所以标准的IF函数最多只能有三个参数。当用户输入的参数超过三个时&#xff0c;Excel就会报这个错误。比如多个IF语句叠加&#xff0c;但可能在嵌套的过程中没有正确关闭每个IF函数的括号&#xff0c;导…...

C#使用文件读写操作实现仙剑五前传称号存档修改

手把手教学仙剑五前传 称号存档修改器 首先找到 Pal5Q所在目录的save\global.sav 文件,这是一个只有488字节的文件,这里存放称号对应的编号ID,以及是否已获得该称号,1为已获取称号,0为未获取称号 [称号:是否获取]这是一个键值对 称号的编号ID是一个Int32数字,使用C#的方法Bi…...

Python 发布 Web 应用的常见方法及详细步骤

以下是 Python 发布 Web 应用的常见方法及详细步骤&#xff0c;涵盖从本地开发到生产环境部署的全流程&#xff1a; 一、基础准备&#xff1a;开发 Web 应用 1. 选择框架&#xff08;以 Flask 为例&#xff09; # app.py from flask import Flask app Flask(__name__)app.ro…...

记录一次部署PC端网址全过程

当我查看我之前写的文章时、顿时惊奇发出感慨&#xff1a;啥时候写的&#xff1f;是我写的么&#xff1f;疑惑重重… 所以说&#xff0c;好记性不如烂笔头。 记录一次部署PC端网址全过程 部署PC端网址分是三步&#xff1a;第一步&#xff1a;申请域名并映射到外网IP &#xff0…...

Spring——Spring开发实战经验(4)

摘要 本文深入探讨了 Spring 应用中 Interceptor&#xff08;拦截器&#xff09;、Filter&#xff08;过滤器&#xff09;和 Aspect&#xff08;切面&#xff09;的执行顺序、职责及典型使用场景。Filter 是 Servlet 级别的机制&#xff0c;主要用于日志记录、权限验证等&…...

深入探索HarmonyOS——构建万物智联的新时代

作者&#xff1a;林钟雪 引言 在科技日新月异的今天&#xff0c;操作系统作为连接硬件与软件的核心桥梁&#xff0c;正引领着数字化转型的新浪潮。HarmonyOS&#xff0c;作为华为自主研发的面向万物智联时代的分布式全场景操作系统&#xff0c;自发布以来便备受瞩目。它不仅打…...

算法12-贪心算法

一、贪心算法概念 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;从而希望导致全局最优解的算法。贪心算法的核心思想是“局部最优&#xff0c;全局最优”&#xff0c;即通过一系列局部最优选择&#xff0c;最…...

小白win10安装并配置yt-dlp

需要yt-dlp和ffmpeg 注意存放路径最好都是全英文 win10安装并配置yt-dlp 一、下载1.下载yt-dlp2. fffmpeg下载 二、配置环境三、cmd操作四、yt-dlp下视频操作 一、下载 1.下载yt-dlp yt-dlp地址 找到win的压缩包点下载&#xff0c;并解压 2. fffmpeg下载 ffmpeg官方下载 …...

I²C简介

前言 IC&#xff08;Inter-Integrated Circuit, 内置集成电路&#xff09;总线是由Philips公司&#xff08;现属于恩智浦&#xff09;在上世纪80年代开发的两线式串行通信总线&#xff0c;用于连接微控制器及其外围设备&#xff0c;控制设备之间的通信。 IC总线的物理拓扑示意…...

Spring容器扩展点

Spring容器扩展点 BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessorImportSelectorImportBeanDefinitionRegistorBeanPostProcessorInstantiationAwareBeanPostProcessor--postProcessBeforeInstantiationSmartInstantiationAwareBeanPostProcessor--determineCan…...

spring boot知识点3

1.spring boot能否使用xml配置 可以&#xff0c;但是很繁琐&#xff0c;现在都建议走JavaConfig 2.spring boot的核心配置文件 application.properties application.yml 3.bootstrap.properties和application.properties的区别 b&#xff1a;用于远程配置 a&#xff1a;…...

Linux后台启动命令nohup并且MobaXterm后台启动断网也不关闭软件

nohup主要作用就是可以在后台运行&#xff0c;并可以选择将日志输出到指定文件。如启动一个程序&#xff0c;若使用./demo的方式启动程序当窗口关闭的时候程序也停止了&#xff0c;而且日志会直接输出到控制台非常不直观&#xff0c;nohup启动就可以解决这两个问题。 nohup与&…...

C++(23):unreachable

C++23在头文件 "><utility>定义了std::unreachable(),用于指示编译器,该段代码不应该被允许,因此编译器可以对该位置进行优化,如果一旦允许了该位置的代码,行为未定义: #include <utility> #include <iostream>using namespace std;int func(…...

【Vue+python】Vue调用python-fastApi接口实现数据(数值、列表类型数据)渲染

前言&#xff1a;之前做的一直都是SpringBootVue的应用&#xff0c;但现在需要实现一个能将python实现的算法应用展示在前端的界面。想法是直接Vue调用python-fastApi接口实现数据渲染~ 文章目录 1. 变量定义2. axios调用python3. 跨域问题解决4. 数据渲染4.1 数值数据渲染4.2 …...

构建高效智能对话前端:基于Ant Design X 的deepseek对话应用

文章目录 实现的效果前言Ant Design X添加欢迎组件创建对话气泡存储对话历史渲染对话气泡 输入组件WebSocket 连接总结 实现的效果 待机页面&#xff1a; 等待页面&#xff1a; 完成页面&#xff1a; 前言 随着人工智能技术的飞速发展&#xff0c;大模型对话系统已成为…...

四元数如何用于 3D 旋转(代替欧拉角和旋转矩阵)【ESP32指向鼠标】

四元数如何用于 3D 旋转&#xff08;代替欧拉角和旋转矩阵&#xff09; 在三维空间中&#xff0c;物体的旋转可以用 欧拉角、旋转矩阵 或 四元数 来表示。 四元数相比于欧拉角和旋转矩阵有 计算更高效、避免万向锁、存储占用少 等优点&#xff0c;因此广泛用于 游戏开发、机器…...