2015-12-10 11 views
6

bzcompressの実装のおかげで、PHPでbzip2のアーカイブデータを作成するのは非常に簡単です。私の現在のアプリケーションでは、すべての理由で入力ファイルを文字列に読み込み、bzcompressまたはbzwriteを呼び出すことはできません。比較的少量のデータでbzwriteを連続して呼び出すと、1回のスウォープでファイル全体を圧縮する場合と同じ結果が得られるかどうかは、PHPのドキュメントではわかりません。私はmakeBZFileを使用し、私は二つのことPHPの大きなファイルのための細かいbzcompression

  • をした

    $data = file_get_contents('/path/to/bigfile'); 
    $cdata = bzcompress($data); 
    

    の線に沿って何か私はこのコードをテストするには

    function makeBZFile($infile,$outfile) 
    { 
    $fp = fopen($infile,'r'); 
    $bz = bzopen($outfile,'w'); 
    while (!feof($fp))  
    { 
        $bytes = fread($fp,10240); 
        bzwrite($bz,$bytes); 
    } 
    bzclose($bz); 
    fclose($fp); 
    } 
    
    function unmakeBZFile($infile,$outfile) 
    { 
    $bz = bzopen($infile,'r'); 
    while (!feof($bz)) 
    { 
        $str = bzread($bz,10240); 
        file_put_contents($outfile,$str,FILE_APPEND); 
    } 
    } 
    
    set_time_limit(1200); 
    makeBZFile('/tmp/test.rnd','/tmp/test.bz'); 
    unmakeBZFile('/tmp/test.bz','/tmp/btest.rnd'); 
    

    下に示したルーチンを使用して断片的なbzcompressionを試してみたことを意味し、 unmakeBZFileを圧縮してから、SQLiteデータベースを圧縮解除してください。これは最終的に必要な作業です。

  • 私はdiff original.file decompressed.fileを行い、両者が同一であったことが分かったランダムデータの両方の場合においてdd if=/dev/urandom of='/tmp.test.rnd bs=50M count=1

で満たさ50MBを作成しました。

非常にいいですが、なぜこれが機能しているのかはわかりません。 PHPドキュメントでは、bzread(bzpointer,length)は最大lengthバイト、のデータは、というデータがありません。私のコードが以下のようなものなら、それはbzwitebzreadのサイズを10240バイトに強制しているからです。

私が見ることができないことbzreadUNCOMPRESSEDデータのlenthバイトをフェッチする方法を知っているだけの方法です。私はformat of a bzip2 fileをチェックアウトしました。 .bzファイルのチャンクの非圧縮データ長を簡単に確立するのに役立つ情報はありません。

私はこれがどのように機能するかについての私の理解に間違いがあると思っています。そうでなければ、以下の私のコードが正しく断片的な圧縮を実行するように見えるという事実はまったく偶然です。

ここではいくつかの説明をよく読んでいただきたいと思います。

答えて

3

圧縮解除がバイトの長さをどのように取得するかを理解するには、最初に圧縮を理解する必要があります。あなたは圧縮アルゴリズムについて何も知らないようです。

BZIP2

BZIP2の重要なアルゴリズムは、コードを次のに適した形式に元のデータを変換するBurrows Wheeler transformation (BWT)、です。現在のバージョンではHuffman codeが適用されます。圧縮アルゴリズムは、ブロック内のデータを各ブロックから完全に独立して処理します。ブロックサイズは、1〜9(100,000〜900,000バイト)の範囲で設定できます。

BZIP2データ構造圧縮された文字列の最初の2つの文字は文字「BZ」と使用algorigthimため、その後、1バイトで始まります。その後すぐにブロックサイズの識別が行われ、ファイル全体(h1,h2,h3~h9)に有効です。このパラメータは、ブロックサイズを1〜9(100,000〜900,000バイト)の単位で示します。

実際の元のデータは、選択されたサイズに従ってブロックに格納され、CRC32チェックサムで個別に保護されます。さらに、48ビットの識別子は各ブロックを導入する。このブロック構造は、損傷したファイルの部分的な再構成を可能にする。

GZIP/BZIP

gzipとBZIP2は、機能的に等価です。 GZIPの利点の1つは、ストリームを圧縮することができることです。ストリームは、後ろに見えないシーケンスです。これはhttpストリームの公式な圧縮者になります。 GZZIP DEFLATE RFC 1951圧縮データ形式仕様書とGUNZIP RFC 1952ファイル形式仕様書は公開された文書です。

GIPは

GZIP Explained

+0

を説明したが答えてくれてありがとう。私の質問では、私は質問をする前に私が研究していたBZIPファイル形式へのリンクを提供していることに気づいたかもしれません。あなたの答えは 'bzwrite'が断片的にデータを書き込む方法を理解するのに役立ちます。 'bzread'が指定された数の*圧縮されていない*バイトをどのように管理するかは、私にはあまり明確ではありません。圧縮の程度は各ブロックのデータによって異なりますので、「* Xバイトの非圧縮データが必要なので、次のX/uncompressed_sizeブロックを取得してください」 – DroidOS

+0

ストレートジャケットではありません圧縮されていないバイトでバイトを読み取るための式。最初に、ハフマンツリーはメモリ内でデコードされ、ツリーに従って圧縮データは圧縮解除される。 – Vineet1982

+0

あなたが知る必要があることは何でも知っておくか、答えを受け入れる – Vineet1982

関連する問題