gpt4 book ai didi

php - HTML5 切片,结果文件已损坏

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:09:40 27 4
gpt4 key购买 nike

我有一个文件上传功能,使用 html5 的切片 api,我将每个文件切成 1MB 的 block ,但最终结果导致文件损坏。有时,最终结果比原始文件小,有时即使大小正确,我仍然无法打开它。有人知道吗?或解决方案?这是切片的部分

        var uploaders = [];
var i = 0;
$(document).ready(function() {
var progress = document.querySelector('progress');
var bars = document.querySelector('#bars');
});

//function for after the button is clicked, slice the file
//and call upload function
function sendRequest() {
//clean the screen
bars.innerHTML = '';
var blob = document.getElementById('fileToUpload').files[0];
var originalFileName = blob.name;
const BYTES_PER_CHUNK = 1 * 1024 * 1024; // 10MB chunk sizes.
const SIZE = blob.size;

var start = 0;
var end = BYTES_PER_CHUNK;

while( start < SIZE ) {
if (blob.webkitSlice) {
var chunk = blob.webkitSlice(start, end);
} else if (blob.mozSlice) {
var chunk = blob.mozSlice(start, end);
}

uploadFile(chunk, originalFileName);
start = end;
end = start + BYTES_PER_CHUNK;
}
}

function uploadFile(blobFile, fileName) {
var progress = document.createElement('progress');
progress.min = 0;
progress.max = 100;
progress.value = 0;
bars.appendChild(progress);

var fd = new FormData();
fd.append("fileToUpload", blobFile);

var xhr = new XMLHttpRequest();
xhr.open("POST", "upload.php"+"?"+"file="+fileName + i, true);
i++;

xhr.onload = function(e) {
//make sure if finish progress bar at 100%
progress.value = 100;

//counter if everything is done using stack
uploaders.pop();

if (!uploaders.length) {
bars.appendChild(document.createElement('br'));
bars.appendChild(document.createTextNode('DONE :)'));
}
};

// Listen to the upload progress for each upload.
xhr.upload.onprogress = function(e) {;
if (e.lengthComputable) {
progress.value = (e.loaded / e.total) * 100;
}
};

uploaders.push(xhr);
xhr.send(fd);
}

这是接受二进制 block 的 php 文件

<?php

$target_path = "uploads/";
$tmp_name = $_FILES['fileToUpload']['tmp_name'];
$size = $_FILES['fileToUpload']['size'];
$name = $_FILES['fileToUpload']['name'];

$originalName = $_GET['file1'];

print_r("*******************************************\n");

print_r($originalName);
print_r("\n");

print_r($_FILES);
print_r("\n");

print_r("*******************************************\n");
$target_file = $target_path . basename($name);

//Result File
$complete = $originalName;
$com = fopen("uploads/".$complete, "ab");
error_log($target_path);

if ( $com ) {
// Read binary input stream and append it to temp file
$in = fopen($tmp_name, "rb");
if ( $in ) {
while ( $buff = fread( $in, 1048576 ) ) {
fwrite($com, $buff);
}
}
fclose($in);
fclose($com);
}


?>

我认为我在将文件与我的 php 代码一起放在服务器上时做错了(比如我没有按顺序排列或其他什么),但有人知道如何做这个或最佳实践吗?与其先上传文件再合并,不如先将其保存在内存中,然后再实际写入文件。

最佳答案

一次上传一个文件的多个 block ,然后在最后合并。

const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes.
var slices;
var slices2;

function sendRequest() {
var xhr;
var blob = document.getElementById('fileToUpload').files[0];

var start = 0;
var end;
var index = 0;

// calculate the number of slices we will need
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
slices2 = slices;

while(start < blob.size) {
end = start + BYTES_PER_CHUNK;
if(end > blob.size) {
end = blob.size;
}

uploadFile(blob, index, start, end);

start = end;
index++;
}
}

function uploadFile(blob, index, start, end) {
var xhr;
var end;
var fd;
var chunk;
var url;

xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.responseText) {
alert(xhr.responseText);
}

slices--;

// if we have finished all slices
if(slices == 0) {
mergeFile(blob);
}
}
};

if (blob.webkitSlice) {
chunk = blob.webkitSlice(start, end);
} else if (blob.mozSlice) {
chunk = blob.mozSlice(start, end);
}

fd = new FormData();
fd.append("file", chunk);
fd.append("name", blob.name);
fd.append("index", index);

xhr.open("POST", "upload.php", true);
xhr.send(fd);
}

function mergeFile(blob) {
var xhr;
var fd;

xhr = new XMLHttpRequest();

fd = new FormData();
fd.append("name", blob.name);
fd.append("index", slices2);

xhr.open("POST", "merge.php", true);
xhr.send(fd);
}

使用 upload.php 收集片段:

if(!isset($_REQUEST['name'])) throw new Exception('Name required');
if(!preg_match('/^[-a-z0-9_][-a-z0-9_.]*$/i', $_REQUEST['name'])) throw new Exception('Name error');

if(!isset($_REQUEST['index'])) throw new Exception('Index required');
if(!preg_match('/^[0-9]+$/', $_REQUEST['index'])) throw new Exception('Index error');

if(!isset($_FILES['file'])) throw new Exception('Upload required');
if($_FILES['file']['error'] != 0) throw new Exception('Upload error');

$target = "uploads/" . $_REQUEST['name'] . '-' . $_REQUEST['index'];

move_uploaded_file($_FILES['file']['tmp_name'], $target);

// Might execute too quickly.
sleep(1);

使用 merge.php 合并片段:

if(!isset($_REQUEST['name'])) throw new Exception('Name required');
if(!preg_match('/^[-a-z0-9_][-a-z0-9_.]*$/i', $_REQUEST['name'])) throw new Exception('Name error');

if(!isset($_REQUEST['index'])) throw new Exception('Index required');
if(!preg_match('/^[0-9]+$/', $_REQUEST['index'])) throw new Exception('Index error');

$target = "uploads/" . $_REQUEST['name'];
$dst = fopen($target, 'wb');

for($i = 0; $i < $_REQUEST['index']; $i++) {
$slice = $target . '-' . $i;
$src = fopen($slice, 'rb');
stream_copy_to_stream($src, $dst);
fclose($src);
unlink($slice);
}

fclose($dst);

关于php - HTML5 切片,结果文件已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9690183/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com