我有一个源目录,其中包含一些我需要复制到我的Web应用程序目录的文件更新。在将文件复制到位之前,我需要备份要写入备份的每个原件。我无法将整个Web应用程序备份到备份位置,因为这将是00的文件。我需要保持dir结构(没有扁平化)&所有3个地点都有相同的结构。
我的主意是两个阶段。备份然后更新。更新很简单(copy& fileset)。备份导致我出现问题,因为我只想备份将要更新的文件。
下面是我当前的迭代(不起作用)...使用带有todir的副本作为备份位置,然后有一个搜索源文件的文件集,所以我有一组更改文件。我显然需要做的是更改文件集返回的文件的路径,以便它们引用现有文件而不是新文件。那就是我被困住的地方。任何人都知道如何更改文件集返回的文件的路径?我使用下面的路径转换,我知道这是错误的,但我把它留下来显示我想要的转换 - 有谁知道怎么做?或者更好的方式!!
${backup.dir} --> root of file backup
${console.war} --> location of existing files - the top of the application dir
${update.dir} --> root of updated files
<copy todir="${backup.dir}/app/console.war">
<fileset dir="${update.dir}/app/console.war" includes="**" id="id.update.files"/>
<pathconvert refid="id.update.files" property="custom.file.target">
<map from="${update.dir}/app/console.war" to="${console.war}"/>
</pathconvert>
</copy>
答案 0 :(得分:0)
最终解决了这个问题。 不得不使用ant-contrib,但这个网站没问题。 关键是使用with和从那时起我的pathconvert是好的。 下面是工作代码供参考 - 我确信它可能更清晰,但它正在工作。
<for param="source.filename">
<path>
<fileset dir="${update.dir}" id="id.src.files">
<include name="**"/>
</fileset>
</path>
<sequential>
<!-- using the source.filename, build the target.filename -->
<local name="target.filename"/>
<local name="target.dirname"/>
<pathconvert property="target.filename">
<file file="@{source.filename}" />
<map from="${update.dir}" to="${console.war}" />
</pathconvert>
<dirname property="target.dirname" file="${target.filename}"/>
<!-- using the source filename build the backup filename -->
<local name="backup.filename"/>
<pathconvert property="backup.filename">
<file file="@{source.filename}" />
<map from="${update.dir}" to="${backup.dir}" />
</pathconvert>
<if>
<available file="${target.filename}"/>
<then>
<copy tofile="${backup.filename}">
<filelist dir="${target.dirname}">
<file name="${target.filename}"/>
</filelist>
</copy>
</then>
</if>
<copy file="@{source.filename}" tofile="${target.filename}"/>
<echo message=""/>
</sequential>
</for>
答案 1 :(得分:0)
您可能需要尝试以下操作:
<copy todir="${backup.dir}/app/console.war">
<fileset dir="${console.war}">
<and>
<different targetdir="${update.dir}/app/console.war"
ignorecontents="true" ignorefiletimes="false"/>
<not>
<depend targetdir="${update.dir}/app/console.war"/>
</not>
</and>
</fileset>
</copy>
此处,and
,different
,not
和depend
为selectors。
上面的代码从fileset
中选择不同的文件
到更新目录中的相应文件(相对于
文件大小和修改时间)除了那些比新的更新
它们在更新目录中的相应文件。
(上述代码的确定方式之间存在细微差别 哪些文件已过期以及复制任务默认如何执行此操作, 但仅适用于具有相同修改时间的相应文件 但文件长度不同。)
以下代码可用于创建自包含示例
build.xml
试用上面的代码:
<project name="backup">
<property name="backup.dir" value="backup.dir"/>
<property name="update.dir" value="update.dir"/>
<property name="console.war" value="console.war"/>
<delete dir="${backup.dir}/app/console.war"/>
<delete dir="${update.dir}/app/console.war"/>
<delete dir="${console.war}"/>
<mkdir dir="${backup.dir}/app/console.war"/>
<mkdir dir="${update.dir}/app/console.war"/>
<mkdir dir="${console.war}"/>
<touch datetime="03/27/2015 09:00 AM" file="${update.dir}/app/console.war/aaa"/>
<touch datetime="03/27/2015 09:11 AM" file="${update.dir}/app/console.war/bbb"/>
<touch datetime="03/27/2015 09:11 AM" file="${console.war}/aaa"/>
<touch datetime="03/27/2015 09:11 AM" file="${console.war}/bbb"/>
<touch datetime="03/21/2015 09:11 AM" file="${console.war}/ccc"/>
<touch datetime="03/27/2015 09:22 AM" file="${update.dir}/app/console.war/ccc"/>
<touch datetime="03/27/2015 09:22 AM" file="${update.dir}/app/console.war/ddd"/>
<!-- insert above copy task -->
</project>
验证创建的backup.dir
(文件ccc
)的内容。
(其他文件会被忽略,因为aaa
较新,bbb
年龄相同,而ddd
尚不存在。只有ccc
已过期。)