我需要使用Apache Ant任务获取ZIP文件中的文件名列表,而不需要先解压缩它。同时,它应该是操作系统无关的,例如:如果My.zip包含:
dir1/path/to/file1.html
dir1/path/to/file2.jpg
dir1/another/path/file3.txt
dir2/some/path/to/file4.png
dir2/file5.doc
Ant任务应该返回上述列表,其中包含相对路径+文件名。
以下是使用 zipfileset 和 pathconvert 的解决方案,再用 macrodef 进行包装以便重用:
<project>
<macrodef name="listzipcontents">
<attribute name="file"/>
<attribute name="outputproperty"/>
<sequential>
<zipfileset src="@{file}" id="content"/>
<pathconvert property="@{outputproperty}" pathsep="${line.separator}">
<zipfileset refid="content"/>
<map from="@{file}:" to=""/>
</pathconvert>
</sequential>
</macrodef>
<listzipcontents file="path/to/whatever.zip|war|jar|ear" outputproperty="foobar"/>
<echo>$${foobar} => ${foobar}</echo>
</project>
优点:您可以使用所有的文件集属性,例如包括/排除,如果您需要过滤zip文件内容-只需通过宏定义扩展其他属性即可。此外,zipfileset支持其他存档文件,如jar、war和ear。
这是一种有点残忍的方法,通过 javascript
语言在 Ant 中使用 script
来实现:
<scriptdef name="getfilenamesfromzipfile" language="javascript">
<attribute name="zipfile" />
<attribute name="property" />
<![CDATA[
importClass(java.util.zip.ZipInputStream);
importClass(java.io.FileInputStream);
importClass(java.util.zip.ZipEntry);
importClass(java.lang.System);
file_name = attributes.get("zipfile");
property_to_set = attributes.get("property");
var stream = new ZipInputStream(new FileInputStream(file_name));
try {
var entry;
var list;
while ((entry = stream.getNextEntry()) != null) {
if (!entry.isDirectory()) {
list = list + entry.toString() + "\n";
}
}
project.setNewProperty(property_to_set, list);
} finally {
stream.close();
}
]]>
</scriptdef>
然后可以在<target>
中调用:
<target name="testzipfile">
<getfilenamesfromzipfile
zipfile="My.zip"
property="file.names.from.zip.file" />
<echo>List of files: ${file.name.from.zip.file}.</echo>
</target>
欢迎任何更好的解决方案。