Ant:在目录中查找文件路径

9

我想要找到目录中文件的路径(类似于unix的“find”命令或“which”命令,但需要在各个平台上都能使用),并将其保存为属性。

尝试使用whichresource ant任务,但它并不能胜任此任务(我认为它只适用于查找jar文件内部的内容)。

我希望这是纯ant,而不是编写自己的任务或使用第三方扩展。

请注意,可能会有多个同名文件实例存在于路径中 - 我希望它只返回第一个实例(或者至少可以选择其中一个实例)。

有什么建议吗?

3个回答

26

一种可能性是使用first资源选择器。例如,要在jars目录下的任何地方查找名为a.jar的文件:

<first id="first">
    <fileset dir="jars" includes="**/a.jar" />
</first>
<echo message="${toString:first}" />

如果没有匹配的文件,将不会输出任何内容,否则你将得到第一个匹配项的路径。


太棒了!这个很好用!你能解释一下 toString: 是什么吗? - yonix
3
这只是一种将“Ant类型”序列化的方式。请参见http://ant.apache.org/manual/properties.html#toString。 - martin clayton
尝试了其他三种技术,包括resourcecountconditionavailable,最终采用了这种方法。这是唯一有效的方法。 - tresf

7

这是一个选择第一个匹配文件的示例。逻辑如下:

  • 使用 fileset 查找所有匹配项。
  • 使用 pathconvert 将结果存储在属性中,每个匹配文件之间用换行符分隔。
  • 使用 head filter 匹配第一个匹配文件。

该功能被封装在 macrodef 中以实现重用。

<project default="test">

  <target name="test">
    <find dir="test" name="*" property="match.1"/>
    <echo message="found: ${match.1}"/>
    <find dir="test" name="*.html" property="match.2"/>
    <echo message="found: ${match.2}"/>
  </target>

  <macrodef name="find">
    <attribute name="dir"/>
    <attribute name="name"/>
    <attribute name="property"/>
    <sequential>
      <pathconvert property="@{property}.matches" pathsep="${line.separator}">
        <fileset dir="@{dir}">
          <include name="@{name}"/>
        </fileset>
      </pathconvert>
      <loadresource property="@{property}">
        <string value="${@{property}.matches}"/>
        <filterchain>
          <headfilter lines="1"/>
        </filterchain>
      </loadresource>
    </sequential>
  </macrodef>

</project>

0

我基于martin-clayton的答案创建了一个宏。

示例项目包含宏和从找到的文件中读取的属性文件。

<?xml version="1.0" encoding="utf-8"?>
<project name="test properties file read" default="info">

<macrodef name="searchfile">
    <attribute name="file" />
    <attribute name="path" default="custom,." />
    <attribute name="name" />
    <sequential>
        <first id="@{name}">
            <multirootfileset basedirs="@{path}" includes="@{file}" erroronmissingdir="false" />
        </first>
        <property name="@{name}" value="${toString:@{name}}" />
    </sequential>
</macrodef>

<searchfile name="custom.properties.file" file="config.properties" />
<property file="${custom.properties.file}" />

<target name="info" >
    <echo>
origin ${config.origin}
</echo>

</target>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接