File io Ant:如何为目录中的每个文件执行命令?
我想从Ant构建文件中为目录中的每个文件执行一个命令。File io Ant:如何为目录中的每个文件执行命令?,file-io,ant,build-process,build-automation,File Io,Ant,Build Process,Build Automation,我想从Ant构建文件中为目录中的每个文件执行一个命令。 我正在寻找一个独立于平台的解决方案 我该怎么做 当然,我可以用一些脚本语言编写脚本, 但这将进一步增加项目的依赖性。简短回答 将与嵌套的 Foreach需要 最近ant contrib的更新示例: <target name="foo"> <foreach target="bar" param="theFile"> <fileset dir="${server.src}" casesensitive=
我正在寻找一个独立于平台的解决方案 我该怎么做 当然,我可以用一些脚本语言编写脚本, 但这将进一步增加项目的依赖性。简短回答 将
与嵌套的
Foreach需要
最近ant contrib的更新示例:
<target name="foo">
<foreach target="bar" param="theFile">
<fileset dir="${server.src}" casesensitive="yes">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</fileset>
</foreach>
</target>
<target name="bar">
<echo message="${theFile}"/>
</target>
这将使用${theFile}调用目标“bar”,生成当前文件。ant contrib是邪恶的;编写自定义ant任务
<scriptdef name="bzip2-files" language="javascript">
<element name="fileset" type="fileset"/>
<![CDATA[
importClass(java.io.File);
filesets = elements.get("fileset");
for (i = 0; i < filesets.size(); ++i) {
fileset = filesets.get(i);
scanner = fileset.getDirectoryScanner(project);
scanner.scan();
files = scanner.getIncludedFiles();
for( j=0; j < files.length; j++) {
var basedir = fileset.getDir(project);
var filename = files[j];
var src = new File(basedir, filename);
var dest= new File(basedir, filename + ".bz2");
bzip2 = self.project.createTask("bzip2");
bzip2.setSrc( src);
bzip2.setDestfile(dest );
bzip2.execute();
}
}
]]>
</scriptdef>
<bzip2-files>
<fileset id="test" dir="upstream/classpath/jars/development">
<include name="**/*.jar" />
</fileset>
</bzip2-files>
ant contrib是邪恶的,因为它试图将ant从声明式样式转换为命令式样式。但是xml是一种糟糕的编程语言
相比之下,定制ant任务允许您使用真实的IDE以真实的语言(Java)编写,您可以在其中编写单元测试以确保您具有所需的行为,然后在构建脚本中明确声明所需的行为
只有当您关心编写可维护的ant脚本时,这种咆哮才有意义。如果您不关心可维护性,请尽一切努力:
联合特遣部队提出了一种不使用ant contrib的方法 基本上,因为没有以同样的方式扩展(但?) 扩展了,他建议使用(当然也可以在命令行中运行java程序) 这里有一些例子:
<apply executable="java">
<arg value="-cp"/>
<arg pathref="classpath"/>
<arg value="-f"/>
<srcfile/>
<arg line="-o ${output.dir}"/>
<fileset dir="${input.dir}" includes="*.txt"/>
</apply>
使用
它对每个文件执行一次命令。通过文件集或任何其他资源指定文件。是内置的;不需要额外的依赖关系;不需要自定义任务实现
也可以只运行一次命令,一次将所有文件作为参数追加。使用“并行”属性切换行为
很抱歉迟到了一年。下面是使用javascript和ant scriptdef任务实现这一点的方法,因为scriptdef是ant的核心任务,所以您不需要ant contrib就能让这段代码正常工作
<scriptdef name="bzip2-files" language="javascript">
<element name="fileset" type="fileset"/>
<![CDATA[
importClass(java.io.File);
filesets = elements.get("fileset");
for (i = 0; i < filesets.size(); ++i) {
fileset = filesets.get(i);
scanner = fileset.getDirectoryScanner(project);
scanner.scan();
files = scanner.getIncludedFiles();
for( j=0; j < files.length; j++) {
var basedir = fileset.getDir(project);
var filename = files[j];
var src = new File(basedir, filename);
var dest= new File(basedir, filename + ".bz2");
bzip2 = self.project.createTask("bzip2");
bzip2.setSrc( src);
bzip2.setDestfile(dest );
bzip2.execute();
}
}
]]>
</scriptdef>
<bzip2-files>
<fileset id="test" dir="upstream/classpath/jars/development">
<include name="**/*.jar" />
</fileset>
</bzip2-files>
您可以使用ant contrib任务“for”来迭代任何delimeter分隔的文件列表,默认delimeter为“,” 以下是显示以下内容的示例文件:
<project name="modify-files" default="main" basedir=".">
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<target name="main">
<for list="FileA,FileB,FileC,FileD,FileE" param="file">
<sequential>
<echo>Updating file: @{file}</echo>
<!-- Do something with file here -->
</sequential>
</for>
</target>
</project>
正在更新文件:@{file}
我知道这篇文章确实很老了,但现在经过了一些时间和ant版本,有一种方法可以使用ant的基本功能来实现这一点,我想我应该分享一下
它通过调用嵌套任务(甚至可以调用其他宏)的递归宏定义完成。唯一的约定是使用固定的变量名(这里的元素)
在ant 1.9.1中引入(学分到)
子字符串,非常感谢
内联宏定义元素
我没有设法使分隔符变为variabel,但这可能不是一个主要的缺点。按照blak3r的建议做,并像这样定义您的目标类路径
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</taskdef>
where lib是存储jar的地方所以,我必须包括一些东西?还是我需要一些外部ant库?我遇到了“问题:无法创建任务或foreach类型”。如果我理解正确,这意味着,foreach是一个未知的关键字。。。这是一项急功近利的任务。所以,你必须安装一些东西。参见此处:该示例来自ant contrib中包含的foreach。这里有一个很好的例子,我将更新这个例子以使其生效。嵌套的fileset元素已被弃用,请使用嵌套的路径instead@dude如果你是对的,我应该用Java编写一个定制的ant任务;)ant contrib真的很邪恶。现在我正处于一个大型的蚂蚁构建项目的中间,它强烈地使用I/S/S/OR和ANTLASK,它真的读起来很恐怖。整个过程看起来就像一个转换的批处理/shell脚本,ant所做的所有依赖项都被ant contrib的大量使用彻底关闭了。如果要保持安装干净,请构建自己的任务:-/@不好意思,我不同意。像任何事情一样,您必须知道何时使用ant contrib最符合您的利益。远离if和var之类的东西,使用ant contrib来避免重新发明轮子。而且,它应该是一种脚本语言,从一开始就是命令式的,而不是声明式的。所以它是邪恶的,谁是邪恶的,也许ant contrib是一个先天的邪恶,但black3r对它的使用似乎是合理的,可以这么说。我在2011年才发现这很有用,所以无论如何还是要感谢它!问题是它只执行外部系统命令。它不会直接做任何烦躁的事情。不清楚最初的问题是不是关于这个。基本上你必须在两种不同的情况下使用or。。。这完全是愚蠢的。这不是非常平台独立的,尽管在最初的问题中它是明确要求的……不幸的是,这会耗尽内存并迅速膨胀。是的,它可能会膨胀堆栈,这取决于您处理的文件数。我用大约66个文件(没有增加内存选项)做得非常成功。但是,如果您没有访问ant contrib的权限,这当然是一个选项,它提供了更多功能(例如并行运行)。这非常有用。上面的示例中引用了变量项目
,但没有提供先前的定义。最好能说明或澄清这一点。编辑:n/m,发现project
是访问当前项目的预定义变量。对于那些在JDK8或更高版本中尝试这一点的人,请记住,如果JRE加载的脚本引擎是rhino(对于大多数JDK6和7都是这样),而在Nashorn(从8点开始),那么“importClass”可以工作