【问题标题】:Ant backup files before copy复制前的蚂蚁备份文件
【发布时间】:2015-03-26 18:36:53
【问题描述】:

我有一个源目录,其中包含一些我需要复制到我的网络应用程序目录中的文件更新。在将文件复制到位之前,我需要备份每个将被覆盖到备份的原始文件。我无法将整个 Web 应用程序备份到备份位置,因为那将是 00 的文件。我需要保持 dir 结构(没有展平)& 所有 3 个位置都具有相同的结构。

我目前的想法是分两个阶段进行。备份然后更新。更新很简单(复制和文件集)。备份给我带来了问题,因为我只想备份将要更新的文件。

以下是我当前的迭代(不起作用)...使用带有 todir 的副本作为备份位置,然后有一个搜索源文件的文件集,这样我就有了一组更改文件。我显然需要做的是更改文件集返回的文件的路径,以便它们引用现有文件而不是新文件,这就是我卡住的地方。任何人都知道如何更改文件集返回的文件的路径?我在下面使用了我知道是错误的 pathconvert,但我把它留在里面以显示我所追求的转换 - 有人知道该怎么做吗?或者更好的方法!

${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>

【问题讨论】:

  • 也许你应该使用像rsync这样的工具,它是为同步文件和做备份而设计的。如果您仍然希望在 Ant 脚本中控制所有内容,您可以使用 exec 任务调用 rsync 来执行备份,然后再复制更新的文件。如果您不喜欢使用 rsync,请查看 sync 任务以在执行更新之前执行备份。

标签: ant


【解决方案1】:

最后解决了。 必须使用来自 ant-contrib 的 for,但这对于这个站点来说没问题。 关键是使用 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>

【讨论】:

    【解决方案2】:

    您可能想尝试以下方法:

    <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>
    

    这里,anddifferentnotdependselectors。 上面的代码从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 已过时。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-22
      • 2013-07-13
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      相关资源
      最近更新 更多