سؤال

لقد قمت بإنشاء فصل لإنشاء ملفات 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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top