zoukankan      html  css  js  c++  java
  • php zip文件内容比較类

    php zip 文件比較类,比較两个zip文件的内容,返回新增,删除,及同样的文件列表。临时仅仅支持单层。


    需求:上传一个zip文件,zip内有非常多图片文件。须要对图片文件进行一系列非常耗时的处理。当用户再更新zip文件时。推断zip内文件是否一致,仅仅处理不同的文件。这样可以节省资源与时间,因此须要编写一个可以比較zip内文件的类。


    ZipCompare.class.php

    <?php
    /** Zip Compare class 比較两个zip文件的内容,返回新增,删除,及同样的文件列表,临时仅仅支持单层
    *   Date:   2014-05-18
    *   Author: fdipzone
    *   Ver:    1.0
    *
    *   Func:
    *   public  compare       比較zip文件内容
    *   private getInfo       获取zip内文件列表
    *   private parse         分析两个zip的文件内容
    *   private check         检查zip文件是否正确
    *   private check_handler 检查server是否有安装unzip
    */
    
    class ZipCompare{ // class start
    
        /** 比較zip文件内容,列出不同样的部分
        * @param  String  $zipfile1 zip文件1
        * @param  String  $zipfile2 zip文件2
        * @return Array
        */
        public function compare($zipfile1, $zipfile2){
    
            // 检查是否有安装unzip
            if(!$this->check_handler()){
                throw new Exception('unzip not install');
            }
    
            // 检查zip文件
            if(!$this->check($zipfile1) || !$this->check($zipfile2)){
                throw new Exception('zipfile not exists or error');
            }
    
            // 获取zip内文件列表
            $zipinfo1 = $this->getInfo($zipfile1);
            $zipinfo2 = $this->getInfo($zipfile2);
    
            // 分析两个zip的文件内容,返回同样及不同的文件列表
            return $this->parse($zipinfo1, $zipinfo2);
    
        }
    
    
        /** 获取zip内文件列表
        * @param  String $zipfile zip文件
        * @return Array           zip内文件列表
        */
        private function getInfo($zipfile){
    
            // unzip -v fields
            $fields = array('Length','Method','Size','Cmpr','Date','Time','CRC-32','Name');
    
            // zip verbose
            $verbose = shell_exec(sprintf("unzip -v %s | sed '$d' | sed '$d' | sed -n '4,$p'", $zipfile));
    
            // zip info
            $zipinfo = array();
    
            $filelist = explode("
    ", $verbose);
    
            if($filelist){
                foreach($filelist as $rowdata){
                    if($rowdata==''){
                        continue;
                    }
                    $rowdata = preg_replace('/[ ]{2,}/', ' ', $rowdata); // 将两个或以上空格替换为一个
                    $tmp = array_slice(explode(' ', $rowdata), 1);       // 去掉第一个空格
    
                    $file = array_combine($fields, $tmp);
    
                    $zipinfo[$file['Name']] = $file['Length'].'_'.$file['CRC-32']; // 文件名称,长度,CRC32,用于校验
                }
            }
    
            return $zipinfo;
    
        }
    
    
        /** 分析两个zip文件内容
        * @param  String $zipinfo1
        * @param  String $zipinfo2
        * @return Array
        */
        private function parse($zipinfo1, $zipinfo2){
    
            $result = array(
                    'add' => array(),  // 新增
                    'del' => array(),  // 缺少
                    'match' => array() // 匹配
                );
    
            if($zipinfo1 && $zipinfo2){
    
                // 在zip1但不在zip2的文件
                $result['add'] = array_values(array_diff(array_keys($zipinfo1), array_keys($zipinfo2)));
    
                // 在zip2但不在zip1的文件
                $result['del'] = array_values(array_diff(array_keys($zipinfo2), array_keys($zipinfo1)));
    
                // 同一时候在zip1与zip2的文件
                $match_file = array_values(array_diff(array_keys($zipinfo1), $result['add']));
    
                // 检查同样文件名称的文件内容是否匹配
                for($i=0,$len=count($match_file); $i<$len; $i++){
    
                    if($zipinfo1[$match_file[$i]]==$zipinfo2[$match_file[$i]]){ // match
                        array_push($result['match'], $match_file[$i]);
                    }else{  // not match, change to add
                        array_push($result['add'], $match_file[$i]);
                    }
    
                }
    
            }
    
            return $result;
    
        }
    
    
        /** 检查zip文件是否正确
        * @param  String $zipfile zip文件
        * @return boolean
        */
        private function check($zipfile){
            // 文件存在且能解压
            return file_exists($zipfile) && shell_exec(sprintf('unzip -v %s | wc -l', $zipfile))>1;
        }
    
    
        /** 检查server是否有安装unzip
        * @return boolean
        */
        private function check_handler(){
            return strstr(shell_exec('unzip -v'), 'version')!='';
        }
    
    } // class end
    
    ?>
    demo

    <?php
    
    require "ZipCompare.class.php";
    
    $obj = new ZipCompare();
    $result = $obj->compare('test1.zip','test2.zip');
    
    print_r($result);
    
    ?>

    运行后输出:

    Array
    (
        [add] => Array
            (
                [0] => 9.jpg
            )
    
        [del] => Array
            (
                [0] => 5.jpg
                [1] => 6.jpg
                [2] => 7.jpg
                [3] => 8.jpg
            )
    
        [match] => Array
            (
                [0] => 1.jpg
                [1] => 10.jpg
                [2] => 11.jpg
                [3] => 12.jpg
                [4] => 13.jpg
                [5] => 14.jpg
                [6] => 15.jpg
                [7] => 16.jpg
                [8] => 17.jpg
                [9] => 18.jpg
                [10] => 2.jpg
                [11] => 3.jpg
                [12] => 4.jpg
            )
    
    )

    源代码下载地址:点击查看


  • 相关阅读:
    视频聊天相关技术介绍
    block相关归纳
    block的作用
    block教程
    向appstore提交app流程
    ios xmpp 发送语音图片解决方案
    python 三元运算、列表推倒式、字典推倒式、生成器生成式
    python 生成器
    python 迭代器(第二次总结)
    python 迭代器
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4303284.html
Copyright © 2011-2022 走看看