PHP

2009-08-04 4 views
11

में gzip के साथ बड़ी फ़ाइलों को अनपैक करें, मैं अपनी फ़ाइलों के लिए एक साधारण अनजिप फ़ंक्शन (जैसा कि नीचे देखा गया है) का उपयोग कर रहा हूं, इसलिए मुझे आगे संसाधित होने से पहले फ़ाइलों को अनजिप करने की आवश्यकता नहीं है।PHP

function uncompress($srcName, $dstName) { 
    $string = implode("", gzfile($srcName)); 
    $fp = fopen($dstName, "w"); 
    fwrite($fp, $string, strlen($string)); 
    fclose($fp); 
} 

समस्या यह है कि अगर gzip फ़ाइल बड़ी है (उदाहरण के लिए 50MB) unzipping राम की एक बड़ी राशि की प्रक्रिया के लिए ले जाता है।

प्रश्न: क्या मैं भाग में एक gzipped फ़ाइल पार्स कर सकता हूं और अभी भी सही परिणाम प्राप्त कर सकता हूं? या क्या बड़ी gzip फ़ाइलों को निकालने के मुद्दे को संभालने का एक बेहतर तरीका है (भले ही इसमें कुछ सेकंड लगते हैं)?

उत्तर

41

gzfile() एक सुविधा विधि है जो gzopen, gzread, और gzclose को कॉल करती है।

तो, हाँ, आप मैन्युअल रूप से gzopen कर सकते हैं और फ़ाइल को gunread में gzread कर सकते हैं।

यह 4kB मात्रा में फ़ाइल को असंपीड़ित होगा:

function uncompress($srcName, $dstName) { 
    $sfp = gzopen($srcName, "rb"); 
    $fp = fopen($dstName, "w"); 

    while (!gzeof($sfp)) { 
     $string = gzread($sfp, 4096); 
     fwrite($fp, $string, strlen($string)); 
    } 
    gzclose($sfp); 
    fclose($fp); 
} 
+3

मीठे! प्रक्रिया समय:: 12.1447s, पीक स्मृति उपयोग: से पहले - एक 1 एमबी gzip फ़ाइल कि 48MB को निकालता है पर परीक्षण किया गया 96512kB - अपने समाधान: प्रक्रिया समय: 0.6705s, पीक स्मृति उपयोग: 256KB धन्यवाद :) – Lukas

+0

आप कर सकते हैं gzread कॉल के अंत में संख्या tweaking द्वारा बेहतर प्रदर्शन प्राप्त करें। मैंने हालांकि कोशिश नहीं की है। – Powerlord

+0

20 गुना बेहतर अच्छा है, और बहुत लंबे समय तक पर्याप्त रहेगा। मुझे इस बात को और कोशिश करने के लिए बहुत ही बेताब या बड़ी फाइलों का उपयोग करना होगा :) – Lukas

1

कोशिश

function uncompress($srcName, $dstName) { 
    $fp = fopen($dstName, "w"); 
    fwrite($fp, implode("", gzfile($srcName))); 
    fclose($fp); 
} 

$ लंबाई पैरामीटर के साथ वैकल्पिक है।

+0

ऐसा लगता है जैसे यह दृष्टिकोण बड़ी मात्रा में स्मृति का उपयोग करके मूल दृष्टिकोण के समान होता है। पूरी फाइल को स्मृति में पढ़ा और रखा जा रहा है। – Lukas

+0

एक चर डेटा डेटा (स्ट्रीमिंग के समान) में लोड नहीं होते हैं। ऑब्जेक्ट स्ट्रिंग लोड करने वाला ऑब्जेक्ट मॉडल नहीं है। यह उदाहरण "php_value memory_limit" को प्रभावित नहीं करता है। आपका उदाहरण इस चर को "php.ini" फ़ाइल में प्रभावित करता है। –

1

आप एक लिनक्स मेजबान पर कर रहे हैं, आदेशों को चलाने के लिए आवश्यक privilegies है, और gzip आदेश स्थापित किया गया है, तो आप की तरह shell_exec

कुछ इस तरह एक सा कुछ के साथ यह फोन करने की कोशिश कर सकते, मुझे लगता है, होगा करें:

shell_exec('gzip -d your_file.gz'); 

इस तरह, फ़ाइल PHP द्वारा अनजिप नहीं होगी।


एक sidenote के रूप:

  • लें देखभाल जहां आदेश से (OT एक swith का उपयोग बताने के लिए "को संपीड़ित कि निर्देशिका")
  • आप एक बार देख लेने के लिए चाहते हो सकता है चलाया जाता है escapeshellarg पर भी ;-)
+0

धन्यवाद, मेरे पास खोल का उपयोग है, लेकिन अभी तक इसका उपयोग करना सीखना है। – Lukas

0

maliayas के रूप में उल्लेख किया है, यह एक बग हो सकता है। मुझे लूप के बाहर एक अप्रत्याशित गिरावट का अनुभव हुआ, लेकिन जीजे फ़ाइल को सफलतापूर्वक डिकंप्रेस कर दिया गया है। पूरा कोड इस तरह दिखता है और मेरे लिए बेहतर काम करता है:

function gzDecompressFile($srcName, $dstName) { 
    $error = false; 

    if($file = gzopen($srcName, 'rb')) { // open gz file 

     $out_file = fopen($dstName, 'wb'); // open destination file 

     while (($string = gzread($file, 4096)) != '') { // read 4kb at a time 
      if(!fwrite($out_file, $string)) { // check if writing was successful 
       $error = true; 
      } 
     } 

     // close files 
     fclose($out_file); 
     gzclose($file);  

    } else { 
     $error = true; 
    } 

    if ($error) 
     return false; 
    else 
     return true; 
}