Iterating over all filenames in a directory in Ant

徘徊边缘 提交于 2019-12-21 21:44:23

问题


I need to iterate over all files in a directory. But I need just the name of each file, not absolute paths. Here's my attempt using ant-contrib:

<target name="store">
  <for param="file">
    <path>
      <fileset dir="." includes="*.xqm"/>
    </path>
    <sequential>
      <basename file="@{file}" property="name" />
      <echo message="@{file}, ${name}"/>
    </sequential>
  </for>              
</target>

The problem is that ${name} expression gets evaluated only once. Is there another approach to this problem?


回答1:


From ant manual basename : "When this task executes, it will set the specified property to the value of the last path element of the specified file"
Properties once set are immutable in vanilla ant, so when using basename task within for loop, the property 'name' holds the value of the first file. Therefore antcontrib var task with unset="true" has to be used :

<target name="store">
 <for param="file">
  <path>
   <fileset dir="." includes="*.xqm"/>
  </path>
  <sequential>
   <var name="name" unset="true"/>
   <basename file="@{file}" property="name" />
   <echo message="@{file}, ${name}"/>
  </sequential>
 </for>              
</target>

Alternatively use local task, when using Ant 1.8.x or later :

<target name="store">
 <for param="file">
  <path>
   <fileset dir="." includes="*.xqm"/>
  </path>
  <sequential>
   <local name="name"/>
   <basename file="@{file}" property="name" />
   <echo message="@{file}, ${name}"/>
  </sequential>
 </for>              
</target>

Finally you may use Ant Flaka instead of antcontrib :

<project xmlns:fl="antlib:it.haefelinger.flaka">
 <fl:install-property-handler />

 <fileset dir="." includes="*.xqm" id="foobar"/>

  <!-- create real file objects and access their properties -->
 <fl:for var="f" in="split('${toString:foobar}', ';')">
  <echo>
  #{  format('filename %s, last modified %tD, size %s bytes', f.tofile.toabs,f.tofile.mtime,f.tofile.size)  }
  </echo>
 </fl:for>

  <!-- simple echoing the basename -->
  <fl:for var="f" in="split('${toString:foobar}', ';')">
   <echo>#{f}</echo>
  </fl:for>  

</project>



回答2:


If you're averse to using the var task due to Ant's standard of property immutability, there's a way to do this by taking advantage of the fact that normal property references ("${}")and iterated property references ("@{}") can be nested within one another:

<target name="store">
    <for param="file">
        <path>
            <fileset dir="." includes="*.xqm"/>
        </path>
        <sequential>
            <basename file="@{file}" property="@{file}" />
            <echo message="@{file}, ${@{file}}"/>
        </sequential>
    </for>              
</target>

This way, you'll be creating a new property named after each file name.



来源:https://stackoverflow.com/questions/21888334/iterating-over-all-filenames-in-a-directory-in-ant

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!