js計算文件md5使用spark-md5.js,聽說這個庫使用的是世界上最快的md5算法。javascript
js對文件切片並使用ajax上傳切片:php
let size = file.size; //獲取文件大小 const shardSize = 1024 * 1024; // 塊大小1MB let shardCount = Math.ceil(size/shardSize); //可切成的塊數 for(let i = 0; i < shardCount; i++){ let start = i * shardSize, end = Math.min(size, start + shardSize); let form = new FormData(); form.append('file', file.slice(start, end)); //用slice方法切片 form.append('size', end - start); form.append('name', name); form.append('total', shardCount); form.append('md5', file_md5); //文件md5值 form.append('index', i); //第幾塊 $.ajax({ url: 'upload.php?type=shard', type: "POST", data: form, // async: false, //是否異步上傳,默認true processData: false, //很重要,告訴jquery不要對form進行處理 contentType: false, //很重要,指定爲false才能造成正確的Content-Type success: function (res) { // 成功回調 } } }
php端保存切片html
$path = __DIR__ . '/uploads'; $file = $_FILES['file']; $total = $_POST['total']; $index = $_POST['index']; $size = $_POST['size']; $dst_file = $path . '/' . $name . '-' . $total . ':' . $index; // 切片文件存儲的文件名 if ($file["error"] > 0) { echo json_encode(['code'=>400, 'msg'=>$file["error"]]);die; } else { $res = move_uploaded_file($file['tmp_name'], $dst_file); if ($res) { file_put_contents($dst_file . '.info', $size); // 切片上傳成功,寫一個保存其大小的文件,後續合併是校驗文件用的到 echo json_encode(['code'=>200, 'msg'=>'shard ok']);die; } else { echo json_encode(['code'=>400, 'msg'=>'shard move_uploaded_file error']);die; } }
php端合併java
function mergeFile($name, $total, &$msg) { // 校驗切片文件是否都上傳完成,是否完整 for ($i = 0; $i < $total; $i++) { if (!file_exists($name . '-' . $total . ':' . $i . '.info') || !file_exists($name . '-' . $total . ':' . $i)) { $msg = "shard error $i"; return false; } else if (filesize($name . '-' . $total . ':' . $i) != file_get_contents($name . '-' . $total . ':' . $i . '.info')) { $msg = "shard size error $i"; return false; } } @unlink($name); if (file_exists($name . '.lock')) { //加鎖 防止有其餘進程寫文件,形成文件損壞 $msg = 'on lock'; return false; } touch($name . '.lock'); $file = fopen($name, 'a+'); for ($i = 0; $i < $total; $i++) { //按切片順序寫入文件 $shardFile = fopen($name . '-' . $total . ':' . $i, 'r'); $shardData = fread($shardFile, filesize($name . '-' . $total . ':' . $i)); fwrite($file, $shardData); fclose($shardFile); unlink($name . '-' . $total . ':' . $i); unlink($name . '-' . $total . ':' . $i . '.info'); } fclose($file); unlink($name . '.lock'); return true; }
我也寫好了一個demo,傳送門jquery
下面是這個demo的效果圖:ajax
這個demo有些方面還不夠完善,後續持續完善吧~算法
原文鏈接:json
關於大文件上傳微信
更多分享知識點,請掃碼關注微信公衆號:多線程