文件分片上传 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来处理请求超时的情况

});

}

相关推荐
几何心凉11 分钟前
如何使用 React Hooks 替代类组件的生命周期方法?
前端·javascript·react.js
小堃学编程18 分钟前
前端学习(1)—— 使用HTML编写一个简单的个人简历展示页面
前端·javascript·html
FY_201822 分钟前
键盘输出希腊字符方法
开发语言
西西弗Sisyphus23 分钟前
Python 处理图像并生成 JSONL 元数据文件 - 灵活text版本
开发语言·python
Taichi呀23 分钟前
PyCharm 快捷键指南
ide·python·pycharm
Stara051130 分钟前
基于注意力机制与iRMB模块的YOLOv11改进模型—高效轻量目标检测新范式
人工智能·python·深度学习·神经网络·目标检测·计算机视觉·yolov11
Python猫1 小时前
付费专栏·Python潮流周刊电子书合集(epub、pdf、markdown)下载
python·计算机·pdf·电子书·资料
q567315231 小时前
Go语言多线程爬虫与代理IP反爬
开发语言·爬虫·tcp/ip·golang
Chandler241 小时前
Go语言即时通讯系统 开发日志day1
开发语言·后端·golang
hnlucky1 小时前
通俗易懂版知识点:Keepalived + LVS + Web + NFS 高可用集群到底是干什么的?
linux·前端·学习·github·web·可用性测试·lvs