2013-05-09 29 views
0

此代碼工作正常(但我擔心它會失敗,大輸入文件)。示例1讀取整個文件並且不循環,示例2讀取3k塊並循環直到EOF。base64_decode在循環中運行時創建損壞的圖像

$in = fopen("in.b64", 'r'); 
$out = fopen("out.png", 'wb'); 
if ((!$in) || (!$out)) die ("convert: i/o error in base64 convert"); 
$first = true; 
while (!feof($in)) 
{ 
    $b64 = fread($in,filesize($in_fn)); 
    // strip content tag from start of stream 
    if ($first) 
    { 
     $b64 = substr($b64,strpos($b64,',')+1); 
     $first = false; 
    } 
    $bin = base64_decode($b64); 
    if (!fwrite($out,$bin)) die("convert write error in base64 convert"); 
} 
fclose($in); 
fclose($out); 

儘管此代碼產生腐敗的形象:

$in = fopen("in.b64", 'r'); 
$out = fopen("out.png", 'wb'); 
if ((!$in) || (!$out)) die ("convert: i/o error in base64 convert"); 
$first = true; 
while (!feof($in)) 
{ 
    $b64 = fread($in,3072); 
    // strip content tag from start of stream 
    if ($first) 
    { 
     $b64 = substr($b64,strpos($b64,',')+1); 
     $first = false; 
    } 
    $bin = base64_decode($b64); 
    if (!fwrite($out,$bin)) die("convert write error in base64 convert"); 
} 
fclose($in); 
fclose($out); 
+1

是的,如果你閱讀它分塊,你會打破編碼。 base64中的每個4個輸入字節表示3個輸出字節。不過,不包括空格。 – mario 2013-05-09 17:43:40

回答

1

雖然3072是能被4整除,使得邊界正確地排隊,你正在做一些字符掉它前面的,使其不能正確對齊。另外,base64規範說每64個字符都有一個換行符,這可能會抵消對齊並破壞分析。

我在下面的解決方案中維護一個字符緩衝區來解碼,並且一次僅處理n * 4個字符的塊。作爲一項測試,我一次只能讀取21個字節,而且看起來很有效。一個警告,一次的字節數應該超過字符串的前面(到逗號)的字符數。

$in = fopen("in.b64", 'r'); 
$out = fopen("out.txt", 'wb'); 
if ((!$in) || (!$out)) die ("convert: i/o error in base64 convert"); 
$first = true; 
$buffer = ''; 
while (!feof($in)) 
{ 
    $b64 = preg_replace("/[\s]+/", "", fread($in,21)); 
    // strip content tag from start of stream 
    if ($first) 
    { 
     $b64 = substr($b64,strpos($b64,',')+1); 
     $first = false; 
    } 
    $buffer .= $b64; 
    $length = strlen($buffer); 
    $leftover = $length % 4; 
    if ($leftover == 0) 
    { 
    $chunk = $buffer; 
    $buffer = ''; 
    } 
    else 
    { 
    $chunk = substr($buffer, 0, -$leftover); 
    $buffer = substr($buffer, $length - $leftover); 
    } 

    if (!empty($chunk)) 
    { 
    $bin = base64_decode($chunk); 
    if (!fwrite($out,$bin)) die("convert write error in base64 convert"); 
    } 
} 
fclose($in); 
fclose($out); 
+0

就是這樣。謝謝。 – 2013-05-09 18:28:54