2013-12-13 40 views
4

我在Amazon S3上有許多LZO壓縮的日誌文件,我想從PHP讀取它們。 AWS SDK提供了一個很好的StreamWrapper來有效地讀取這些文件,但由於文件是壓縮的,因此我需要先解壓內容才能處理它。在PHP中解壓縮LZO流

我已經安裝了PHP-LZO extension,讓我做lzo_decompress($data),但因爲我處理流,而不是完整的文件內容,我想我需要在同一時間消耗串一個LZO壓縮塊。換句話說,我想要做的事,如:

$s3 = S3Client::factory($myAwsCredentials); 
$s3->registerStreamWrapper(); 

$stream = fopen("s3://my_bucket/my_logfile", 'r'); 

$compressed_data = ''; 
while (!feof($stream)) { 
    $compressed_data .= fread($stream, 1024); 

    // TODO: determine if we have a full LZO block yet 
    if (contains_full_lzo_block($compressed_data)) { 

     // TODO: extract the LZO block 
     $lzo_block = get_lzo_block($compressed_data); 

     $input = lzo_decompress($lzo_block); 
     // ...... and do stuff to the decompressed input 
    } 

} 
fclose($stream); 

兩個TODO s爲在那裏,我不知該怎麼辦:

  1. 檢查數據流dtermine我是否有充分的LZO塊尚未
  2. 提取該塊減壓

由於壓縮是由亞馬遜(s3distCp)做我沒有超過該塊大小的控制,所以我會probabl你需要檢查輸入的流來確定塊的大小 - 這是一個正確的假設嗎?

(理想情況下,我會直接在流上使用自定義StreamFilter,但我一直沒能找到任何人誰做過那樣的事)

+1

怎麼樣使用一些系統命令解壓LZO文件,而不是實施在PHP下從頭開始解壓縮?我搜索了php lzo庫,發現沒有。 – dendini

+0

通過系統命令解壓就行得通 - 如果有人可以發表一個有效的例子,我很樂意接受這個答案 –

回答

1

好的執行通過PHP命令可以在許多做不同的方式,是這樣的:

$command = 'gunzip -c /path/src /path/dest'; 
$escapedCommand = escapeshellcmd($command); 
system($escapedCommand); 

或也

shell_exec('gunzip -c /path/src /path/dest'); 

將做的工作。 現在,這是一個執行命令的問題,在Linux下有一個很好的命令行工具lzop,它可以提取或壓縮lzop文件。

您可以通過像使用它:

lzop -dN sources.lzo 

所以,你最終的代碼可能會是一件那麼容易,因爲:

shell_exec('lzop -dN s3://my_bucket/my_logfile'); 
+0

這看起來很有前途。我明天會給它一個鏡頭! –