2

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

它正确上传每个块。但在完成上传结束时,我尝试将文件合并回 1 件,但这需要很长时间。如果我尝试刷新上传者的 web ui,它在完成合并之前将无法工作。

我的合并代码是这样的:

$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。

谢谢

4

2 回答 2

2

如果您不想在使用带exec函数的 php 时等待,您可以使用gearman 工作队列和工作人员的异步响应。在工作人员内部,您可以使用@hafichuk 解决方案。队列使您的整个应用程序更具可扩展性。

于 2013-01-08T00:05:20.083 回答
2

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

我会考虑设置一个作业队列来处理连接过程,其中 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);

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

于 2013-01-07T22:57:06.777 回答