gzDeflate () وكمية كبيرة من البيانات
سؤال
لقد قمت بإنشاء فصل لإنشاء ملفات zip في PHP. بديل لـ Ziparchive على افتراض أنه غير مسموح به في الخادم. شيء لاستخدامه مع تلك الخوادم المجانية.
إنه بالفعل نوع من العمل ، وبناء هياكل الرمز البريدي مع PHP ، واستخدام GZDEFlate () لإنشاء البيانات المضغوطة.
المشكلة هي أن GZDEFlate () تتطلب مني تحميل الملف بالكامل في الذاكرة ، وأريد أن يعمل الفصل إلى 32 ميجابايت من الذاكرة. حاليًا تقوم بتخزين الملفات أكبر من 16 ميجابايت دون ضغط على الإطلاق.
أتصور أنني يجب أن أجعلها تضغط على البيانات في كتل ، 16 ميجابايت في 16 ميجابايت ، لكنني لا أعرف كيفية تسلسل نتيجة gzDeflate ().
لقد تم اختباره ويبدو أنه يتطلب بعض الرياضيات في آخر 16 بت ، نوع من buff->last16bits = (buff->last16bits & newblock->first16bits) | 0xfffe
, ، إنه يعمل ، ولكن ليس لجميع العينات ...
سؤال: كيف تسلسل تيارين مفرغتين دون إلغاء ضغطه؟
المحلول
يتم استخدام مرشحات دفق PHP لأداء مثل هذه المهام. stream_filter_append
يمكن استخدامها أثناء القراءة من أو الكتابة إلى التدفقات. فمثلا
$fp = fopen($path, 'r');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_READ);
حاليا fread
سيعود لك البيانات المنهارة.
نصائح أخرى
هذا قد، أو قد لا، يساعد. يبدو أن GZWrite سيسمح لك بكتابة الملفات دون تحميلها بالكامل في الذاكرة. يوضح هذا المثال من صفحة PHP Manual كيف يمكنك ضغط ملف باستخدام 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;
}