代码之家  ›  专栏  ›  技术社区  ›  a4w

使用base64编码大文件

  •  1
  • a4w  · 技术社区  · 7 年前

    我试图在base64编码中对一个数MBs或有时数GBs的文件进行编码/解码,但有些数据以错误的方式进行编码/解码,从而导致出现奇怪的字符,如:。

    我正在逐块读取文件编码并逐个保存(可能这就是问题所在,但我无法解决)。

    以下是我迄今为止所做的尝试:

    <?php
    
    function encode_file($Ifilename, $Efilename){
        $handle = fopen($Ifilename, 'rb');
        $outHandle = fopen($Efilename, 'wb');
        $bufferSize = 8151;
        while(!feof($handle)){
            $buffer = fread($handle, $bufferSize);
            $ebuffer = base64_encode($buffer);
            fwrite($outHandle, $ebuffer);
        }
        fclose($handle);
        fclose($outHandle);
    }
    
    function decode_file($Ifilename, $Efilename){
        $handle = fopen($Ifilename, 'rb');
        $outHandle = fopen($Efilename, 'wb');
        $bufferSize = 8151;
        while(!feof($handle)){
            $buffer = fread($handle, $bufferSize);
            $dbuffer = base64_decode($buffer);
            fwrite($outHandle, $dbuffer);
        }
        fclose($handle);
        fclose($outHandle);
    }
    
    encode_file('input.txt', 'out.bin');//Big text file ~4MBs
    
    decode_file('out.bin', 'out.txt');
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   a4w    6 年前

    阅读完全文后 Wikipedia article 在base64上,我发现每3个字符编码为4个base64字符,这就是导致文件损坏的原因。

    解决方法是在编码时简单地将缓冲区设置为n,其中n是3的倍数。

    解码时,将缓冲区设置为N,其中N是4的倍数。

    工作代码:

    <?php
    function encode_file($Ifilename, $Efilename){
        $handle = fopen($Ifilename, 'rb');
        $outHandle = fopen($Efilename, 'wb');
        $bufferSize = 3 * 256;// 3 bytes of ASCII encodes to 4 bytes of base64
        while(!feof($handle)){
            $buffer = fread($handle, $bufferSize);
            $ebuffer = base64_encode($buffer);
            fwrite($outHandle, $ebuffer);
        }
        fclose($handle);
        fclose($outHandle);
    }
    
    function decode_file($Ifilename, $Efilename){
        $handle = fopen($Ifilename, 'rb');
        $outHandle = fopen($Efilename, 'wb');
        $bufferSize = 4 * 256; // 4 bytes of base64 decodes to 3 bytes of ASCII
        while(!feof($handle)){
            $buffer = fread($handle, $bufferSize);
            $dbuffer = base64_decode($buffer);
            fwrite($outHandle, $dbuffer);
        }
        fclose($handle);
        fclose($outHandle);
    }
    
    encode_file('input.txt', 'out.bin');
    
    decode_file('out.bin', 'output.txt');