О загрузке больших файлов
размышляющий
- Используйте js для чтения файла, выбранного в форме формы, вычисления значения MD5 файла, загрузки значения MD5 на сервер и проверки того, был ли файл загружен (аналогично функции второго прохода).
- Если файл не был загружен, разрежьте его на блоки размером 1 МБ в соответствии с его размером. Если он меньше 1 МБ, не сокращайте его.
- Использование Ajax для асинхронной отправки вырезанного блока и загрузки его на сервер (один блок, один запрос, неблокирующий, многопоточность)
- Когда все блоки загружены, инициируется запрос на объединение файлов, и сервер объединяет ранее загруженные блоки файлов, что означает, что загрузка завершена.
Осуществление
Вычислительный файл JS MD5 использует spark-md5.js, который, как говорят, использует самый быстрый алгоритм MD5 в мире.
JS разрежьте файл и загрузите его с помощью Ajax:
Let size = file. Size; // get the file size
Const shardsize = 1024 * 1024; // block size 1MB
Let shardcount = math.ceil (size / shardsize); // number of blocks that can be cut
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 with slice method
form.append('size', end - start);
form.append('name', name);
form.append('total', shardCount);
Form. Append ('md5 ', file [MD5); // file MD5 value
Form. Append ('index ', I); // block
$.ajax({
url: 'upload.php?type=shard',
type: "POST",
data: form,
//Async: false, // whether to upload asynchronously, true by default
Processdata: false, // very important, tell jQuery not to process the form
Contenttype: false, // it's important to specify false to form the correct content type
success: function (res) {
//Successful callback
}
}
}Сохранить фрагмент в PHP
$path = __DIR__ . '/uploads';
$file = $_FILES['file'];
$total = $_POST['total'];
$index = $_POST['index'];
$size = $_POST['size'];
$dst_file = $path. '/' $name. '-' $total. ':' $index; // the file name stored in the slice file
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); // the slice is uploaded successfully. Write a file to save its size. Subsequent consolidation is used to verify the file.
echo json_encode(['code'=>200, 'msg'=>'shard ok']);die;
} else {
echo json_encode(['code'=>400, 'msg'=>'shard move_uploaded_file error']);die;
}
}Слияние сторон PHP
function mergeFile($name, $total, &$msg)
{
//Verify that the slice files are uploaded and complete
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')) {// lock to prevent other processes from writing files, resulting in file corruption
$msg = 'on lock';
return false;
}
touch($name . '.lock');
$file = fopen($name, 'a+');
For ($I = 0; $I < $total; $I + +) {// writes files in slice order
$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;
}Я также написал демо-версию портала.
Ниже приведен рендеринг этой демо-версии:
Некоторые аспекты этой демонстрации не идеальны. Пожалуйста, продолжайте совершенствоваться позже.
Исходная ссылка:
О загрузке больших файлов
Чтобы поделиться дополнительными знаниями, пожалуйста, отсканируйте код, чтобы обратить внимание на публичный адрес WeChat: