【问题标题】:Combine zip archives in ANT with both filtering and case-sensativity将 ANT 中的 zip 存档与过滤和区分大小写相结合
【发布时间】:2011-10-04 00:37:40
【问题描述】:

我想使用 ANT 将几个 zip 文件组合在一起,但我有三个限制会导致标准技术失败:

  1. 有些文件(具有已知文件名)我不想包含在最终存档中。
  2. 一些源存档包含名称相同但大小写不同的文件。
  3. 运行脚本的机器使用不区分大小写的文件系统。

为了使我的问题具体化,这里有一个示例源存档。我确实知道a.txtA.txt代表的文件名,但我知道知道文件名b.txt

$ touch a.txt ; zip src.zip a.txt ; rm a.txt 
$ touch A.txt ; zip src.zip A.txt ; rm A.txt 
$ touch b.txt ; zip src.zip b.txt ; rm b.txt 
$ unzip -l src.zip 
Archive:  src.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  09-23-11 11:35   a.txt
        0  09-23-11 11:35   A.txt
        0  09-23-11 11:36   b.txt
 --------                   -------
        0                   3 files

这就是我想要的:(原始存档中的所有内容,除了 b.txt)

$ ant
$ unzip -l expected.zip
Archive:  expected.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  09-23-11 11:35   a.txt
        0  09-23-11 11:35   A.txt
 --------                   -------
        0                   2 files

我发现在互联网上推荐的两种技术是:

<target name="unzip-then-rezip">
    <!-- Either a.txt or A.txt is lost during unzip and
         does not appear in out.zip -->
    <delete dir="tmp"/>
    <delete file="out.zip"/>
    <mkdir dir="tmp"/>
    <unzip src="src.zip" dest="tmp"/>
    <zip destfile="out.zip" basedir="tmp" excludes="b.txt"/>
</target>

<target name="direct-zip">
    <!-- Have not found a way to exclude b.txt from out.zip -->
    <delete file="out.zip"/>
    <zip destfile="out.zip">
        <zipgroupfileset dir="." includes="*.zip" />
    </zip>
</target>

使用unzip-then-rezip,我会丢失a.txtA.txt,因为底层文件系统不区分大小写并且不能存储这两个文件。使用direct-zip 似乎是正确的方法,但我还没有找到过滤掉我不想包含的文件的方法。

我将求助于创建自己的 ANT 任务来完成这项工作,但我更愿意使用标准的 ANT 任务(甚至是 ant-contrib),即使会降低性能或可读性。

【问题讨论】:

    标签: ant zip


    【解决方案1】:

    我最终创建了一个自定义 ANT 任务来解决问题。该任务接受嵌套的 excludes 元素,这些元素提供与源 zip 文件中的整体匹配的正则表达式。

    另外,我还能够解决另一个问题:使用嵌套 rename 元素的正则表达式重命名 zip 条目。

    ANT 代码如下所示:

        <filter-zip srcfile="tmp.zip" tgtfile="target.zip">
            <exclude pattern="^b\..*$"/>
            <rename pattern="^HELLO/(.*)" replacement="hello/$1"/>
        </filter-zip>
    

    ANT 任务的内核如下所示:

        zIn = new ZipInputStream(new FileInputStream(srcFile));
        zOut = new ZipOutputStream(new FileOutputStream(tgtFile));
    
        ZipEntry entry = null;
        while ((entry = zIn.getNextEntry()) != null) {
    
            for (Rename renameClause : renameClauses) {
                ...
            }
            for (Exclude excludeClause : excludeClauses) {
                ...
            }
    
            zOut.putNextEntry(...);
            // Copy zIn to zOut
            zOut.closeEntry();
            zIn.closeEntry();
        }
    

    在我最初的问题中,我说我想将几个 zip 文件组合在一起。在原始问题中使用“直接压缩”方法非常简单。我使用它来创建一个中间 zip 文件 (tmp.zip),然后我将其用作我的 filter-zip 任务的源:

        <zip destfile="tmp.zip">
            <zipgroupfileset dir="." includes="*.zip" />
        </zip>
    

    目前我的filter-zip 任务运行速度比zip(组装所有拉链)任务慢一点......所以性能(可能)非常接近理想。将这两个步骤结合在一起将是一个不错的小练习,但对我来说投资回报率不是很高。

    【讨论】:

      【解决方案2】:

      看看 Ant 的 Resource Collections,尤其是像 restrict 这样的东西,它允许您以非常灵活的方式过滤文件(和 zip 文件内容等)。

      这个 sn-p 似乎是你想要的(至少在我的机器上 - OSX):

      <project default="combine">
        <target name="combine">
          <delete file="expected.zip" />
      
          <zip destfile="expected.zip">
            <restrict>
              <zipfileset src="src.zip" />
              <not>
                <name name="b.txt" />
              </not>
            </restrict>
          </zip>
      
        </target>
      </project>
      

      输入文件:

      $ unzip -l src.zip
      Archive:  src.zip
        Length     Date   Time    Name
       --------    ----   ----    ----
              0  09-24-11 00:55   a.txt
              0  09-24-11 00:55   A.txt
              0  09-24-11 00:55   b.txt
       --------                   -------
              0                   3 files
      

      输出文件:

      $ unzip -l expected.zip
      Archive:  expected.zip
        Length     Date   Time    Name
       --------    ----   ----    ----
              0  09-24-11 00:55   A.txt
              0  09-24-11 00:55   a.txt
       --------                   -------
              0                   2 files
      

      【讨论】:

      • 虽然这个答案在技术上是正确的,但当 zip 文件非常大(按条目数)时,它的性能很差。我没有充分调试脚本以找到根本原因,所以我仍然愿意接受任何人关于这个想法的任何建议。同时,我创建了一个自定义 ant 任务,见下文。
      • @drew 你用的是什么版本的ant?
      • Apache Ant(TM) 版本 1.8.2 编译于 2011 年 6 月 3 日。MacOS 10.6.8。为了提供一定的规模,最终的 zip 文件约为 12,000 个文件和 15MByte。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-05
      • 2011-03-08
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      相关资源
      最近更新 更多