代码之家  ›  专栏  ›  技术社区  ›  cypher

用PHP解压较大的文件

  •  6
  • cypher  · 技术社区  · 14 年前

    我正在尝试用PHP解压一个14MB的归档文件,代码如下:

        $zip = zip_open("c:\kosmas.zip");
        while ($zip_entry = zip_read($zip)) {
        $fp = fopen("c:/unzip/import.xml", "w");
        if (zip_entry_open($zip, $zip_entry, "r")) {
         $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
         fwrite($fp,"$buf");
         zip_entry_close($zip_entry);
         fclose($fp);
         break;
        }
       zip_close($zip);
      }
    

    它在我的本地主机上失败,内存限制为128MB,经典“ Allowed memory size of blablabla bytes exhausted “。在服务器上,我有16MB的限制,有没有更好的方法来达到这个限制?我不明白为什么要分配超过128MB的内存。事先谢谢。

    解决方案: 我开始以10千字节的块读取文件,问题解决了峰值内存使用率arnoud 1.5兆。

            $filename = 'c:\kosmas.zip';
            $archive = zip_open($filename);
            while($entry = zip_read($archive)){
                $size = zip_entry_filesize($entry);
                $name = zip_entry_name($entry);
                $unzipped = fopen('c:/unzip/'.$name,'wb');
                while($size > 0){
                    $chunkSize = ($size > 10240) ? 10240 : $size;
                    $size -= $chunkSize;
                    $chunk = zip_entry_read($entry, $chunkSize);
                    if($chunk !== false) fwrite($unzipped, $chunk);
                }
    
                fclose($unzipped);
            }
    
    4 回复  |  直到 10 年前
        1
  •  4
  •   Morgan    11 年前

    你为什么一次读整个文件?

     $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
     fwrite($fp,"$buf");
    

    尝试读取其中的小部分并将其写入文件。

        2
  •  1
  •   46bit    14 年前

    仅仅因为一个zip小于php的内存限制,也许解压的也是,一般不考虑php的开销,更重要的是实际解压文件所需的内存,虽然我对压缩不是很在行,但我希望它可能比最终解压的大小要大得多。

        3
  •  0
  •   Anax    14 年前

    对于这种大小的文件,最好使用 shell_exec() 而是:

    shell_exec('unzip archive.zip -d /destination_path');
    

    PHP必须 在安全模式下运行,您必须能够访问shell exec和unzip才能使此方法工作。

    更新 :

    鉴于命令行工具不可用,我所能想到的就是创建一个脚本并将文件发送到远程服务器,在那里命令行工具 可用,提取文件并下载内容。

        4
  •  0
  •   elad    10 年前
    function my_unzip($full_pathname){
    
        $unzipped_content = '';
        $zd = gzopen($full_pathname, "r");
    
        while ($zip_file = gzread($zd, 10000000)){
            $unzipped_content.= $zip_file;
        }
    
        gzclose($zd);
    
        return $unzipped_content;
    
    }