質問
PHPでZIPファイルを作成するクラスを作成しています。サーバーで許可されていないことを前提としたZipArchiveの代替。これらの無料サーバーで使用するもの。
これはすでに機能し、PHPでZIP構造を構築し、gzdeflate()を使用して圧縮データを生成します。
問題は、gzdeflate()を使用すると、ファイル全体をメモリにロードする必要があり、32MBのメモリに制限して動作するようにクラスを設定することです。現在、圧縮なしで16MBを超えるファイルを保存しています。
16MB x 16MBのブロック単位でデータを圧縮する必要があると思いますが、2つのgzdeflate()の結果を連結する方法がわかりません。
私はそれをテストしてきましたが、最後の16ビットで何らかの計算が必要なようです。 buff-> last16bits =(buff-> last16bits& newblock-> first16bits)| 0xfffe
、動作しますが、すべてのサンプルではありません...
質問:解凍せずに2つのDEFLATEDストリームを連結するにはどうすればよいですか?
解決
このようなタスクを実行するには、PHPストリームフィルターが使用されます。 stream_filter_append
を使用できますストリームの読み取りまたは書き込み中。例
$fp = fopen($path, 'r');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_READ);
Now fread
は、収縮したデータを返します。
他のヒント
これは役立つ場合とできない場合があります。 gzwriteを使用すると、メモリに完全にロードせずにファイルを書き込むことができます。 PHPマニュアルページのこの例は、gzwriteとfopenを使用してファイルを圧縮する方法を示しています。
http://us.php.net/manual/en/function .gzwrite.php
function gzcompressfile($source,$level=false){
// $dest=$source.'.gz';
$dest='php://stdout'; // This will stream the compressed data directly to the screen.
$mode='wb'.$level;
$error=false;
if($fp_out=gzopen($dest,$mode)){
if($fp_in=fopen($source,'rb')){
while(!feof($fp_in))
gzwrite($fp_out,fread($fp_in,1024*512));
fclose($fp_in);
}
else $error=true;
gzclose($fp_out);
}
else $error=true;
if($error) return false;
else return $dest;
}