+ -
当前位置:首页 → 问答吧 → 压缩整个目录(两个同样功能的程序)

压缩整个目录(两个同样功能的程序)

时间:2007-01-23

来源:互联网

不错的类,支持支持。

作者: gently   发布时间: 2007-01-22

呵呵~~~
又被加精华了,谢谢!!
在给个我改过的压缩文件的类,这个完全像winrar一样哦
复制PHP内容到剪贴板
PHP代码:
class ZipLib{//压缩文件夹
    
    var $datasec      = array();
    var $ctrl_dir     = array();
    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
    var $old_offset   = 0; 
    var $dirs         = array(".");
    function IniVars(){//初始化变量
        $this -> datasec      = array();
        $this -> ctrl_dir     = array();
        $this -> eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
        $this -> old_offset   = 0;
        $this -> dirs         = array(".");
    }
    function ZipFolder($dir,$zipfilename){//压缩一个文件夹 
        if(substr($dir,0,2)=="./"){
                $dir = substr($dir,2);
        }elseif(substr($dir,0,1)=="/"){
                $dir = substr($dir,1);
        }
        $this->AddFolderContent($dir);
        $out = $this -> get_file();
        $this -> IniVars();
        $fp = fopen($zipfilename,"w");  
        fwrite($fp,$out,strlen($out));  
        fclose($fp);
    }
    
    function AddFolderContent($dir){//添加文件夹中文件列表到 $this->dirs
        if(is_dir($dir)){
            if(!in_array($dir,$this->dirs)){
                $this->add_Dir($dir);
            }
            $handle = opendir($dir);
            while($files = readdir($handle)){
                if (($files==".")||($files=="..")) continue; 
                if(is_dir($dir."/".$files)){
                    $this->AddFolderContent($dir."/".$files);
                }else{
                    $fp = fopen ($dir."/".$files,"r");
                    $content = @fread ($fp,filesize($dir."/".$files));  
                    fclose ($fp);  
                    $this->add_File($content,$dir."/".$files);
                }
            }  
            closedir($handle);
        }
    }
    
    function ZipFileArray($files,$zipfilename){//混杂压缩 文件和文件夹并排压缩
        if(!is_array($files)){ 
            $files = array($files);
        }
        for($i=0;$files[$i];$i++){//这儿用的很妙!我看到这种使用方法时,大吃一惊,第一次在这用
            $fn = $files[$i];
            if(substr($fn,0,2)=="./"){
                $fn = substr($fn,2);
            }elseif(substr($fn,0,1)=="/"){
                $fn = substr($fn,1);
            }
            if(!in_array(dirname($fn),$this->dirs)){
                $this->add_Dir(dirname($fn));
            }
            if(basename($fn)&&is_file($fn)){
                $fp   = fopen ($fn, "r");  
                $data = @fread ($fp,filesize($fn));  
                fclose ($fp);
                $this->add_File($data,$fn);
            }elseif(basename($fn)&&is_dir($fn)){
                $this->AddFolderContent($fn);
            }
        }
        $out = $this -> get_file();
        $this -> IniVars();
        $fp = fopen($zipfilename,"w");  
        fwrite($fp,$out,strlen($out));  
        fclose($fp);
    }
    
    function get_file(){//获得压缩文件数据
        $data = implode('', $this -> datasec);
        $ctrldir = implode('', $this -> ctrl_dir);
        return $data . $ctrldir . $this -> eof_ctrl_dir .
        pack('v', sizeof($this -> ctrl_dir)).pack('v', sizeof($this -> ctrl_dir)).
        pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00";
    }
    
    function add_dir($name){ 
        $name   = str_replace("\\", "/", $name); 
        $fr     = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 
        $fr    .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 
        $fr    .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0); 
        $this -> datasec[] = $fr;
        $new_offset = strlen(implode("", $this->datasec)); 
        $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 
        $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 
        $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 ); 
        $ext = "\xff\xff\xff\xff"; 
        $cdrec .= pack("V", 16 ).pack("V", $this -> old_offset ).$name; 
        $this -> ctrl_dir[] = $cdrec; 
        $this -> old_offset = $new_offset; 
        $this -> dirs[] = $name;
    }
    
    function add_File($data, $name, $compact = 1){
        $name     = str_replace('\\', '/', $name);
        $dtime    = dechex($this->DosTime());
        $hexdtime = '\x' . $dtime[6] . $dtime[7].'\x'.$dtime[4] . $dtime[5] . '\x' . $dtime[2] . $dtime[3].'\x'.$dtime[0].$dtime[1];
        eval('$hexdtime = "' . $hexdtime . '";');
        if($compact){
            $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime;
        }else{
            $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime;
        }
        $unc_len = strlen($data); $crc = crc32($data);
        if($compact){
            $zdata = gzcompress($data); $c_len = strlen($zdata);
            $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
        }else{
            $zdata = $data;
        }
        $c_len=strlen($zdata);
        $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
        $fr .= pack('v', strlen($name)).pack('v', 0).$name.$zdata;
        $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
        $this -> datasec[] = $fr;
        $new_offset        = strlen(implode('', $this->datasec));
        if($compact){
            $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00";
        }else{ 
            $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00";
        }
        $cdrec .= $hexdtime.pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
        $cdrec .= pack('v', strlen($name) ).pack('v', 0 ).pack('v', 0 );
        $cdrec .= pack('v', 0 ).pack('v', 0 ).pack('V', 32 );
        $cdrec .= pack('V', $this -> old_offset );
        $this -> old_offset = $new_offset;
        $cdrec .= $name;
        $this -> ctrl_dir[] = $cdrec;
        return true;
    }
    
    function DosTime() {
        $timearray = getdate();
        if ($timearray['year'] < 1980) {
            $timearray['year'] = 1980; $timearray['mon'] = 1;
            $timearray['mday'] = 1; $timearray['hours'] = 0;
            $timearray['minutes'] = 0; $timearray['seconds'] = 0;
        }
        return (($timearray['year']-1980)<<25)|($timearray['mon']<<21)|($timearray['mday']<<16)|($timearray['hours']<<11)|($timearray['minutes']<<5)|($timearray['seconds']>>1);
    }
}

//例子
$zip = new ZipLib();
$zip->ZipFileArray("./sourceold","./new.zip");
$zip->ZipFolder("./baby","new2.zip");

[ 本帖最后由 muqiao 于 2007-1-24 18:34 编辑 ]

作者: muqiao   发布时间: 2007-01-24

好东西,怎么没人顶?老大,请问如何改成7z(ip)的

作者: cntime   发布时间: 2007-02-21

哥们再搞个解压缩的!

作者: 早谷   发布时间: 2007-04-10

支持

作者: 默默   发布时间: 2007-04-11

引用:
原帖由 早谷 于 2007-4-10 23:33 发表
哥们再搞个解压缩的!
正在研究
其实早就有了啊

不过太庞大了

准备研究它的思路,简化它一下

先上传一下,有想法的先改一下

作者: muqiao   发布时间: 2007-04-11

你的精神,非常感谢!

作者: 早谷   发布时间: 2007-04-13

哥们,把整个代码都贴上来学习下撒!

作者: wukeyuan   发布时间: 2007-04-13

支持一下!

作者: liumingl   发布时间: 2007-04-15

老大,给各说明文档啊

作者: skyjhz   发布时间: 2007-04-21

使用了下还不错,嘿嘿收藏;P

作者: skyjhz   发布时间: 2007-04-21

  学习一下,先赞一个。

作者: 特蓝克斯   发布时间: 2007-04-23

不错,顶

作者: yustar   发布时间: 2007-04-24

研究下

作者: �����i�i   发布时间: 2007-04-24

window上可以,linux上不行.你们试了是怎样的?

作者: sunceenjoy   发布时间: 2008-05-27