我想使用ANT将几个zip文件组合在一起,但我有三个限制导致标准技术失败:
为了使我的问题具体,这是一个示例源存档。我不知道a.txt
和A.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.txt
或A.txt
,因为底层文件系统不区分大小写,无法存储这两个文件。使用direct-zip
似乎是正确的方法,但我还没有找到一种方法来过滤掉我不想包含的文件。
我即将创建自己的ANT任务来完成这项工作,但我更倾向于使用标准的ANT任务(甚至是ant-contrib),即使存在性能或可读性惩罚。
答案 0 :(得分:1)
我最终创建了一个自定义ANT任务来解决问题。该任务接受嵌套的excludes
元素,这些元素提供与源zip文件中的entires匹配的正则表达式。
作为额外的奖励,我还能解决另一个问题:使用嵌套的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文件组合在一起。在原始问题中使用“direct-zip”方法非常简单。我使用它来创建一个中间zip文件(tmp.zip
),然后我将其用作filter-zip
任务的源:
<zip destfile="tmp.zip">
<zipgroupfileset dir="." includes="*.zip" />
</zip>
目前我的filter-zip
任务运行速度慢于zip
(组装所有拉链)任务...所以性能(可能)非常接近理想状态。将这两个步骤结合在一起将是一个很好的小练习,但对我来说投资回报率不是很高。
答案 1 :(得分:0)
查看Ant的Resource Collections,特别是restrict
等允许您以非常灵活的方式过滤文件(和zip文件内容等)的内容。
这个片段看起来像你想要的(至少在我的机器上 - 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