如何使用Ant的“同步”任务,但基于文件内容

时间:2011-05-09 18:30:11

标签: ant

我真的很喜欢Ant'同步'任务,但我需要做的是根据目标文件的内容是否与源文件的内容相匹配,将文件从源文件夹复制到目标文件夹,而不是检查文件修改日期(这是'同步'当前所做的事情)。有没有办法实现这个目标?我注意到有一个用于文件内容的Ant比较器,以及一个可能派上用场的“校验和”任务。

谢谢!

3 个答案:

答案 0 :(得分:5)

对于遇到此问题且需要代码的任何其他人,此处是基于内容而非时间戳同步一个位置与另一个位置的任务,它使用已修改选择器而不是不同< / strong>选择器在另一个答案中,可以更好地控制文件差异的计算方式:

<project name="Demo" default="newSync">
  <description>
    Sync from ${foo} to ${bar}
  </description>

  <macrodef name="syncContents">
    <attribute name="from"/>
    <attribute name="to"/>
    <sequential>
      <fileset id="selectCopyFiles" dir="@{from}">
        <modified algorithm="hashvalue"/>
      </fileset>
      <fileset id="selectDeleteFiles" dir="@{to}">
        <not>
          <present targetdir="@{from}"/>
        </not>
      </fileset>

      <copy overwrite="true" todir="@{to}">
        <fileset refid="selectCopyFiles"/>
      </copy>
      <delete includeEmptyDirs="true">
        <fileset refid="selectDeleteFiles"/>               
      </delete>
    </sequential>
  </macrodef>

  <target name="newSync">
    <syncContents from="${foo}" to="${bar}"/>
  </target>
</project>

请注意,这会使条形镜像foo(同步A-> B),如果您想要双向同步,则可以使用B-&gt; A中的副本替换删除,并提供一个concat任务来处理对两个位置都有相同的文件。

答案 1 :(得分:2)

我能够使用Ant的'copy'任务完成此任务,该任务具有带different选择器的文件集(请参阅http://ant.apache.org/manual/Types/selectors.html#differentselect)。这是强大的东西。

答案 2 :(得分:1)

感谢您完成此任务!

但是,selectCopyFiles文件集不正确。我还有另一个selectDeleteFiles文件集的解决方案。

以下是macrodef的新代码:

<macrodef name="syncContents">
    <attribute name="from"/>
    <attribute name="to"/>
    <sequential>
        <echo>syncContents     : @{from} -> @{to}</echo>
        <fileset id="selectCopyFiles" dir="@{from}">
            <different targetdir="@{to}"
             ignoreFileTimes="true"/>
        </fileset>
        <fileset id="selectDeleteFiles" dir="@{to}">
            <present present="srconly" targetdir="@{from}"/>
        </fileset>

        <copy overwrite="true" todir="@{to}" preservelastmodified="true" verbose="true">
            <fileset refid="selectCopyFiles"/>
        </copy>
        <delete includeEmptyDirs="true" verbose="true">
            <fileset refid="selectDeleteFiles"/>
        </delete>
        <echo>End syncContents : @{from} -> @{to}</echo>
    </sequential>
</macrodef>