欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

大文件切片功能

发布时间:2025/7/25 编程问答 55 豆豆
生活随笔 收集整理的这篇文章主要介绍了 大文件切片功能 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

近期接到的新需求:上传大文件,因文件上传的大小不定,所以需要切片上传
前端代码:

import md5 from "js-md5";/*** 缓存转换 导入大文件* @param {*} that this* @param {*} file 上传文件的对象* @param {*} size 每次上传文件的限制大小* @param {*} progress 上传文件的进度条* @param {*} url string 上传文件的url* @param {*} module_name string 上传文件的需要上文的文件名*/ export function uploadFile(that, file, size, progress, url, module_name) {let xhr = new XMLHttpRequest();let form_data = new FormData();let start = 0;let end = start + that.size;let blob;let blob_num = 1;blob = cutFile(file);sendFile(blob, file);blob_num += 1;//切割文件function cutFile(file) {let file_blob = file.slice(start, end);start = end;end = start + that.size;return file_blob;};//发送文件function sendFile(blob, file) {let total_blob_num = Math.ceil(file.size / size);form_data = new FormData();form_data.append('file', blob);form_data.append('blob_num', blob_num);form_data.append('total_blob_num', total_blob_num);form_data.append('file_name', file.name);form_data.append('module_name', module_name);form_data.append('code', md5(md5(file.name + global.ENCRYPTION_KEY)));xhr.open("POST", global.IMG_URL + url, false);xhr.onreadystatechange = function () {if (total_blob_num == 1) {that.progress = 100;} else {that.progress = Math.min(100, (blob_num / total_blob_num) * 100);}if (JSON.parse(xhr.response).code == 0) {that.file_name = '';that.$Message.error('上传错误');return false} else if (JSON.parse(xhr.response).code == 2) {that.$Message.success('上传成功');that.file_path = JSON.parse(xhr.response).file_path;return false}let t = setTimeout(function () {if (start < file.size) {blob = cutFile(file);sendFile(blob, file);blob_num += 1;} else {clearTimeout(t);}}, 1000);}xhr.send(form_data);} }

后端代码:我们后端是用PHP完成的

<?phpif (!defined('BASEPATH')) exit('No direct script access allowed'); header('Content-Type:text/html;charset=utf-8');header('Access-Control-Allow-Origin:*');class chunkupload extends CI_Controller {private $filepath; // 上传目录private $tmpPath; // PHP文件上传临时目录private $blobNum; // 当前第几个文件块private $totalBlobNum; // 文件块总数private $fileName; // 原文件名private $finalFileName; // 经过处理的最终文件名public function __construct(){parent::__construct();}// 大文件分片上传public function bigFileUpload(){if (empty($_POST['code'])) {echo_json(0,'code不能为空');}if (empty($_POST['module_name'])) {echo_json(0,'上传目录不能为空');}if (empty($_POST['blob_num'])) {echo_json(0,'当前片数不能为空');}if (empty($_POST['file_name'])) {echo_json(0,'文件名不能为空');}if (empty($_POST['total_blob_num'])) {echo_json(0,'总片数不能为空');}if (empty($_FILES['file'])) {echo_json('file为空');}if (empty($_FILES['file']['tmp_name'])) {echo_json(0,'tmp_name为空');}$fileDir = './uploads/'.trim($_POST['module_name'],'/').'/' . date('Y/m/d');$this->filepath = $fileDir;$this->tmpPath = $_FILES['file']['tmp_name'];$this->blobNum = $_POST['blob_num'];$this->totalBlobNum = $_POST['total_blob_num'];$this->fileName = $_POST['file_name'];// 校验$this->validate($_POST['code'], $_POST['file_name']);// 移动文件$this->moveFile();// 合并分块的文件$this->fileMerge();// 响应状态$this->apiReturn();}// 判断是否是最后一块,如果是则进行文件合成并且删除文件块private function fileMerge(){if($this->blobNum == $this->totalBlobNum){$blob = '';for($i=1; $i<= $this->totalBlobNum; $i++){$blob .= file_get_contents($this->filepath.'/'. $this->fileName.'__'.$i);}$ext = '.'.substr(strrchr($this->fileName, '.'), 1);$this->finalFileName = date('YmdHis') . rand('10000', '99999') . $ext;file_put_contents($this->filepath.'/'. $this->finalFileName,$blob);$this->deleteFileBlob();}}// 删除文件块private function deleteFileBlob(){for($i=1; $i<= $this->totalBlobNum; $i++){@unlink($this->filepath.'/'. $this->fileName.'__'.$i);}}// 移动文件private function moveFile(){$this->touchDir();$filename = $this->filepath.'/'. $this->fileName.'__'.$this->blobNum;move_uploaded_file($this->tmpPath,$filename);}// API返回数据public function apiReturn(){header('Content-type: application/json');if($this->blobNum == $this->totalBlobNum){if(file_exists($this->filepath.'/'. $this->finalFileName)){$data['code'] = 2;$data['msg'] = 'success';$data['file_path'] = ltrim($this->filepath,'./').'/'. $this->finalFileName;echo json_encode($data);exit;}}else{if(file_exists($this->filepath.'/'. $this->fileName.'__'.$this->blobNum)){$data['code'] = 1;$data['msg'] = '上传中,共:'.$this->totalBlobNum.'块,当前第'.$this->blobNum.'块....';$data['file_path'] = '';echo json_encode($data);exit;}}}// 建立上传文件夹private function touchDir(){if(!file_exists($this->filepath)){return mkdir($this->filepath, 0777, true);}}// 参数校验private function validate($code,$fileName){if (md5(md5($fileName.config_item('encryption_key'))) != $code) {echo_json(0,'参数校验失败');}} }function echo_json($code = 0, $msg = '', $data = array()) {$arr = array('code' => $code,'msg' => $msg,'data' => $data);echo json_encode($arr);exit; }

 

转载于:https://www.cnblogs.com/mxyr/p/10343039.html

总结

以上是生活随笔为你收集整理的大文件切片功能的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。