【问题标题】:Transfer a file of any type in 1k chunks over HTTP通过 HTTP 以 1k 块传输任何类型的文件
【发布时间】:2023-04-02 23:33:01
【问题描述】:

我需要通过 HTTP/GET 以大约 1k 块传输任何类型或大小的文件。生成的文件哈希需要与源文件匹配。这需要在本地 PHP 中完成,无需任何特殊工具。我有一个基本的策略,但我得到了奇怪的结果。这个概念证明只是在本地复制文件。

代码

<?php

    $input="/home/lm1/Music/Ellise - Feeling Something Bad.mp3";
    $a=pathinfo($input);
    $output=$a["basename"];

    echo "\n> ".md5_file($input);
    $fp=fopen($input,'rb');

    if ($fp) {

        while(!feof($fp)) {
            $buffer=base64_encode(fread($fp,1024));
            // echo "\n\n".md5($buffer);
            write($output,$buffer);
        }
        fclose($fp);
        echo "\n> ".md5_file($output);
        echo "\n";
        
    }   
    
    function write($file,$buffer) { 
        // echo "\n".md5($buffer);
        $fp = fopen($file, 'ab');
        fwrite($fp, base64_decode($buffer));
        fclose($fp);    
    }   
    
?>

输出

> d31e102b1cae9c73bbf5a12615a8ea36
> 9f03f6c88ed61c07cb534922d6d31864

提前致谢。

【问题讨论】:

    标签: php binaryfiles


    【解决方案1】:

    fread 已经推进了文件指针的位置,因此无需跟踪它。与frwite 相同,因此连续调用会自动附加到给定文件。因此,您可以简化您的方法(代码改编自this answer,关于如何有效地将大型输入流写入文件):

    $src  = "a.test";
    $dest = "b.test";
    
    $fp_src = fopen($src, 'rb');
    
    if ($fp_src) {
        
        $fp_dest     = fopen($dest, 'wb');
        $buffer_size = 1024;
    
        while(!feof($fp_src)) {
            
            fwrite($fp_dest, fread($fp_src, $buffer_size));
        }
    
        fclose($fp_src);
        fclose($fp_dest);
    
        echo md5_file($src)."\n";  // 88e4af2f85080a280e7f00e50d96b7f7
        echo md5_file($dest)."\n"; // 88e4af2f85080a280e7f00e50d96b7f7
    }
    

    如果你想让两个进程分开,你会这样做:

    $src  = "a.test";
    $dest = "b.test";
    
    if (file_exists($dest)) {
    
        unlink($dest); // So we don't append to an existing file
    }
    
    $fp = fopen($src,'rb');
    
    if ($fp) {
    
        while(!feof($fp)){
    
            $buffer = base64_encode(fread($fp, 1024));
            write($dest, $buffer);
        } 
    
        fclose($fp);
    }
    
    function write($file, $buffer) { 
        
        $fp = fopen($file, 'ab');
    
        fwrite($fp, base64_decode($buffer));
        fclose($fp);    
    }   
    
    echo md5_file($src)."\n";  // 88e4af2f85080a280e7f00e50d96b7f7
    echo md5_file($dest)."\n"; // 88e4af2f85080a280e7f00e50d96b7f7
    

    关于如何通过 HTTP 流式传输文件,您可能想看看:

    【讨论】:

    • 我能够根据您的示例显着改进代码,谢谢。但在我的情况下,读写将发生在不同的系统上。当我将缓冲区的读/写和 base64 分开时,它们似乎在期间匹配,但生成的文件要大得多,当然还有不同的哈希值。
    • 我已经扩展了我的答案,所以我的第二个示例现在应该非常接近您的代码 - 我真正改变的唯一一件事是检查目标文件是否存在,如果存在则删除它.一开始我完全错过了,也许你也错过了?
    • 哈哈,是的,我做到了!像魅力一样工作,谢谢。
    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 2018-10-03
    • 2015-11-03
    • 1970-01-01
    • 2017-03-08
    • 2016-05-25
    相关资源
    最近更新 更多