首页 > 其他分享 >上传大文件

上传大文件

时间:2024-03-30 16:35:55浏览次数:20  
标签:文件 const formData file 分片 上传 any

import { Upload, Button, message, Progress } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { useRef, useState } from 'react';
import SparkMD5 from 'spark-md5';
import { bigUpload, bigUploads } from '../api/forum';
//上传文件的接口

// 计算文件的 MD5 值
function calculateMD5(file: any) {
  return new Promise((resolve) => {
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();
    const chunkSize = 5 * 1024 * 1024;
    let currentChunk = 0;

    fileReader.onload = function (e: any) {
      spark.append(e.target.result);
      currentChunk++;
      if (currentChunk < chunks) {
        loadNext();
      } else {
        const result = spark.end();
        resolve(result);
      }
    };

    // 加载下一个分片
    function loadNext() {
      const start = currentChunk * chunkSize;
      const end = Math.min(file.size, start + chunkSize);
      const buffer = file.slice ? file.slice(start, end) : file.webkitSlice(start, end); // 使用 slice 方法
      fileReader.readAsArrayBuffer(buffer);
    }

    const chunks = Math.ceil(file.size / chunkSize); // 文件划分成的分片数量
    loadNext(); // 开始加载第一个分片
  });
}

// 将文件划分成多个分片
function chunkFile(file: any, chunkSize: any) {
  const chunks = Math.ceil(file.size / chunkSize); // 文件划分成的分片数量
  const chunksList = [];
  let currentChunk = 0;

  while (currentChunk < chunks) {
    const start = currentChunk * chunkSize;
    const end = Math.min(file.size, start + chunkSize);
    const chunk = file.slice ? file.slice(start, end) : file.webkitSlice(start, end); // 使用 slice 方法
    chunksList.push(chunk); // 将分片添加到列表中
    currentChunk++;
  }

  return chunksList; // 返回分片列表
}

const App = () => {
  const [uploading, setUploading] = useState(false); // 是否正在上传文件的状态
  const [progress, setProgress] = useState(0); // 文件上传进度的状态
  const chunkRefs: any = useRef([]); // 保存分片引用的引用
  const md5Ref: any = useRef(''); // 保存 MD5 值的引用

  const handleFileChange = async ({ file }: any) => {
    setUploading(true); // 开始文件上传
    const md5 = await calculateMD5(file); // 计算文件的 MD5 值
    md5Ref.current = md5; // 保存 MD5 值到引用

    // 将文件划分成多个分片并保存到引用对象中
    const chunksList: any = chunkFile(file, 5 * 1024 * 1024);
    console.log(
      'chunksListchunksListchunksListchunksListchunksListchunksListchunksList',
      chunksList
    );
const data:any = []
    chunkRefs.current = chunksList.map(async (chunk: any, index: any) => {
      const formData = new FormData();
      formData.append('multipartFile', chunk);
      formData.append('fileName', file.name);
      formData.append('totalBlockCount', chunksList.length);
      formData.append('totalBlockSort', index.toString());
      formData.append('fileMd5Value', md5Ref.current); // 添加 MD5 参数
      console.log("formData",formData,md5Ref.current,index.toString(),file.name,chunk);
      data.push(formData)
      return formData;
    });
    console.log('dfsdfsdfdsfdsfdsf递四方速递佛挡杀佛', chunkRefs.current[0]);


    // 定义递归函数用于逐个上传分片
    const uploadChunk = async (index: any) => {
      if (index >= chunkRefs.current.length) {
        // 所有分片上传完成
        console.log("所有分片上传完成");
        bigUploads({fileMd5Value:md5Ref.current}).then(res=>{
        console.log("sssssss",res);
        
      })
        message.success('文件上传成功!');
        setUploading(false); // 文件上传完成,修改上传状态
        return;
      }
      console.log('index', index);

      try {
        await bigUpload(data[index]); // 调用上传函数上传当前分片,此处为调用上传的接口
        console.log(`分片 ${index + 1} 上传成功`);
        // 更新进度条的值
        const newProgress = Math.ceil(((index + 1) / chunkRefs.current.length) * 100);
        setProgress(newProgress);
        // 递归调用上传下一个分片
        await uploadChunk(index + 1);
        return;
      } catch (error) {
        console.error(`分片 ${index + 1} 上传失败`, error);
        message.error('文件上传失败!');
        setUploading(false); // 文件上传失败,修改上传状态
        return;
      }
    };

    // 开始递归上传第一个分片
    await uploadChunk(0);
  };

  const handleRemove = () => {
    // 清空保存的分片引用、MD5 引用和重置进度条
    chunkRefs.current = [];
    md5Ref.current = '';
    setProgress(0);
  };

  return (
    <div>
      <Upload
      maxCount={1}
        name="file"
        multiple={false}
        beforeUpload={() => false}
        onChange={handleFileChange}
        onRemove={handleRemove} // 添加自定义的删除操作
      >
        <Button loading={uploading} icon={<UploadOutlined />}>
          {uploading ? '上传中' : '选择文件'}
        </Button>
      </Upload>
      {uploading && <Progress percent={progress} status="active" />}
    </div>
  );
};

export default App;

  

export function bigUploads(data: any) {
  return http.request({
    url: '/Learning/merge',
    method: 'post',
    data
  });
}


export function bigUpload(formData: any) {
  return axios({
    url: "http://192.168.2.135:8009/admin/fisp/Learning/shardingUpload",
    method: 'POST',
    headers: {
      // "Content-Type":"application/force-download",
      Authorization:  unescape(localStorage.getItem('httpurl') as string),
      'User-Agent': navigator.userAgent
    },
    data: formData
  }).then((res) => {
  console.log("水电费反反复复反反复复发发发",res);
  
    return res;
  });
}

  

标签:文件,const,formData,file,分片,上传,any
From: https://www.cnblogs.com/zjxzhj/p/18105673

相关文章

  • 文件管理(C语言)
    文章目录文件管理文件文件的打开/关闭fopenfclose文件的顺序读/写fputcfgetcfputsfgetsfwritefreadfprintffscanf文件的随机读写fseekftellrewind文件结束标志的判定feofferror总结读取文件的函数的返回值fgetcfgetsfread补充函数sprintfsscanf文件缓冲区文件......
  • 文件上传漏洞防御
    参考文章:文件上传漏洞-原理篇_文件上传漏洞,find提权-CSDN博客网络安全-文件上传漏洞的原理、攻击与防御_文件上传漏洞原理-CSDN博客网络安全课第七节文件上传漏洞的检测与防御_$post=file_get_contents("php://input");-CSDN博客文件上传漏洞概念:文件上传漏洞发生在有......
  • 文件操作系列
    欢迎到来的各位,这一篇的内容稍微有点多,请耐心观看呦!下面进入正题!!目录1.为什么使用文件?2.什么是文件?2.1程序文件2.2数据文件2.3文件名3.二进制文件和文本文件?4.文件的打开和关闭4.1流和标准流4.1.1流4.1.2标准流4.2文件指针4.3文件的打开和关闭4.3......
  • spring boot 配置文件值注入
        利用配置文件将属性注入到bean程序里面去,下面是各个情况的总结:    首先我先新建一个bean(beans.User类)来完成演示:packageorg.example.springbootdemo.beans;importlombok.Data;importorg.springframework.boot.context.properties.ConfigurationPro......
  • Vue怎么使用Upload组件进行图片上传到阿里云OSS,并
    基于前端用Vue2后端用Springboot进行讲解一、创建阿里云OSS       对象存储OSS_云存储服务_企业数据管理_存储-阿里云(aliyun.com),打开网站进行开通    开通后我们来到Bucket列表,创建Bucket            创建过程:后面就默认就行了   ......
  • C语言中的数据文件的操作
    接下来我们开启今天的C语言之旅吧~1. 为什么使用文件?如果没有文件,我们写的程序的数据是储存在电脑中的内存中,如果程序退出,内存回收,数据就会回收,等再次运行程序,是看不到上次程序的数据的,如果将数据进行持久化的保存,我们就可以是文件。2.什么是文件?磁盘(硬盘)上的文件。......
  • pyinstaller将文件内容打包到可执行文件本身中
    本文使用创作助手。要将文件内容打包到可执行文件本身中,可以使用PyInstaller的--add-data选项和pyz文件格式。以下是具体步骤:将所有的图片和音频文件放入一个文件夹,例如resources文件夹。在你的代码中,使用相对路径引用这些文件。例如:importosimage_path=os.path.jo......
  • Json文件格式及Cpp解析
    JSON(JavaScriptObjectNotation)用于存储和传输数据,通常用于服务器-->Web端的数据传输JSON示例:{"employees":[{"firstName":"John","lastName":"Doe"},{"firstName":"Anna","lastN......
  • Linux(4)常见操作整理-静态路由-双网卡-文件上传下载-运维思路-性能监测方法-jar包查找
    五、常见操作1、静态路由配置【描述】:当前ifconfigeno16777728对应ip:172.41.0.120【解决】:(1)[root@localhost~]#cd/etc/sysconfig/network-scripts/(2)添加文件:route-eno16777728​172.41.200.0/24via172.41.0.253deveno16777728​172.41.202.0/24via172......
  • 接收文件流并导出至excel以及对二进制文件流内容的校验
    废话不说上代码consthandleRightDownload=async()=>{axios({method:'post',url:'/my/handleAndDownloadExcel',//请求地址这里写后端的地址,注意加上`/api`以确保最终的请求能被替换掉,/api表示server要替换的前缀'/api'->''data:{......