php - 如何快速高效地将文件 block (html5 分块的结果)合并到一个文件中

标签 php html file-upload file-io file-transfer

我创建了一个文件传输程序,它使用 html5 分块上传文件(大约 4GB 的大文件)。每个 block 的大小为 100MB(我只是无缘无故地选择这个,因为我尝试使用 10MB,据我所知,它实际上没有任何区别)。

它正确上传每个 block 。但在上传完成后,我尝试将文件合并回一份,但这需要很多时间。如果我尝试刷新上传者的网络用户界面,则在完成合并之前它将无法工作。

我的合并代码是这样的:

$final_file_path = fopen($target_path.$file_name, "ab");


//Reconstructed File
for ($i = 0; $i <= $file_total_chunk; $i++) {
    $file_chunk = $target_path.$file_name.$i;    

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

fclose($final_file_path);   

有什么办法可以高效、快速地做到这一点吗?我正在使用 PHP。

谢谢

最佳答案

您可能应该考虑将上传和串联过程分成两个单独的过程。上传和通知用户文件已上传(通过网页)可以一起完成,后端处理可能应该在完全独立的过程中完成。

我会考虑设置一个作业队列来处理串联过程,其中 PHP 上传脚本一旦完成,就会将一个作业放入队列中,并且服务器上运行的守护进程会生成一个工作线程来执行串联。

就个人而言,我会让工作人员使用 cat 进行串联。

$> cat chunk_1 chunk_2 ... chunk_n > uploaded_file_name

如果您仍然想在 PHP 中执行此操作,那么您可以执行以下操作:

for ($1 = 0; $i <= $file_total_chunk; $i++) {
    $files[] = $target_path.$file_name.$i;
}

$catCmd = "cat " . implode(" ", $files) . " > " . $final_file_path;
exec($catCmd);

确保您已清理文件名,否则有可能注入(inject)将在此处的命令行上执行的任意代码。

关于php - 如何快速高效地将文件 block (html5 分块的结果)合并到一个文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14205445/

相关文章:

mongodb - 使用 GridFS 在 MongoDB 中存储图像是否有效?

asp.net-mvc - 尝试使用 ASP.NET MVC 上传文件

php - 为什么在PHP或其他语言中使用动态变量(可变变量)

php - MYSQL JOIN所有子行,父行只显示一次

php - Smarty 如何从 foreach 获取第一个索引?

php - 使网页在网络托管域上运行所需的帮助

amazon-web-services - 使用 AWS EC2 实例提高上传速度

php - Laravel PDO::exec() 期望参数 1 为字符串,给定对象

css - HTML 5 元素重叠

html - 如何根据屏幕大小更改背景图像?