上传大文件
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; }); }
本文来自博客园,作者:zjxgdq,转载请注明原文链接:https://www.cnblogs.com/zjxzhj/p/18105673