Andy Jarrett // Code. Develop. Create.

Ant- Copying files and directories

I know that I've done a post on copying files with Ant, but I really want to take this further and into more detail. To save my fingers a lot of the text below is taken from my first post as moving and copying directories/files is a similar command in principle.

I also want to mention that I am running all my Ant tasks via Eclipse and not the command line. If there is a demand to know how to install Ant and run it from the command line I'll do that post separately. At this point I'm assuming you've got Eclipse and you know your way around it enough? Before we do begin you will need to ensure that you can see the Console 'View', you can get to this by going to:

Window >> Show View >> Other >> General >> Console

Before we jump in, if you are on Unix then know that the file permissions are not retained when files are copied; they end up with the default UMASK permissions instead. This is down to the current Java runtimes and the inability to set the permissions. You can get around this by using ANT to call Copy Path view the terminal i.e. instead. If you are on Windows and you copy a file to a directory where that file already exists, but with different casing, the copied file takes on the case of the original. The workaround is to delete the file in the destination directory before you copy it.

Let's begin!

Create a new project in your Eclipse workspace. The type of project doesn't matter, though I'm creating a CFEclipse one as I want to copy .cfm pages. From within the project create a new file called Build.xml. Create two more folders in your Ant project called 'folder_test' and 'folder_live' and in the first folder put a file called 'index.cfm'. Your project should now look like this:

  • build.xml
    • [folder_live]
    • [folder_test]
      • index.cfm

The idea of the next task is to copy index.cfm from the test folder to the live one. I'm also going to introduce properties, think of them as variables.

<?xml version="1.0" encoding="UTF-8"?>
<project name="myFirstBuildFile" default="" basedir=".">
    <description> A description of what this build file does </description>
    <!-- Relative location of test folder -->
    <property name="test" value="folder_test/" />
    <!-- Relative location of live folder -->
    <property name="live" value="folder_live/" />
    <!-- copy file -->
    <copy file="${test}index.cfm" todir="${live}" />
    <echo message="The index.cfm file has been copied" />
</project>

Now while still in the editor right-click anywhere on your build.xml file and choose the following:

Run As >> Ant Build

If all has gone well you should have just copied your index.cfm file from test to live. That's all good and well but I doubt you ever have to copy just one file, my guess is that you have a host of folders and files. In the directory 'folder_test' add two other directories called 'images' and 'css' and copy 'index.cfm' back as well. Your new directory structure should look like this: (feel free to stick some more files into the newly created folders)

  • build.xml
    • [folder_live]
    • [folder_test]
      • [css]
      • [images]
      • index.cfm

The plan now is to copy the complete directory of 'folder_test' to 'folder_live':

<?xml version="1.0" encoding="UTF-8"?>
  <project name="myFirstBuildFile" default="" basedir=".">
    <description> A description of what this build file does </description>
    <!-- Relative location of test folder -->
    <property name="test" value="folder_test/" />
    <!-- Relative location of live folder -->
    <property name="live" value="folder_live/" />
    <!-- copy directories and files -->
    <!-- From Ant 1.6.3 you can write the following as: -->
    <!-- <copy file="${test}" tofile="${live}" /> -->
    <copy todir="${live}">
      <fileset dir="${test}" />
    </copy>
    <echo message="The contents of folder_test have been copied" />
  </project>

Again while in the editor right-click anywhere on your build.xml file and choose the following:

Run As >> Ant Build

Of course, there is more you can do. Rather than going through a full set of examples here, or some of the other features:

Copy a set of files to a directory

 <copy todir="${live}">
  <fileset dir="${test}">
    <exclude name="**/*.cfm" />
  </fileset>
</copy>
<copy todir="${live}">
  <fileset dir="${test}" excludes="**/*.cfm" />
</copy>

Copy a set of files to a directory, appending .bak to the file name on the fly

<copy todir="${live}">
  <fileset dir="${test}" />
  <globmapper from="*" to="*.bak" />
</copy>

Copy a set of files to a directory, replacing @TITLE@ with Foo Bar in all files.

<copy todir="${live}">
  <fileset dir="${test}" />
  <filterset>
    <filter token="TITLE" value="Foo Bar" />
  </filterset>
</copy>

Collect all items from the current CLASSPATH setting into a destination directory, flattening the directory structure.

<copy todir="${live}" flatten="true">
  <path>
    <pathelement path="${test}" />
  </path>
</copy>

Copies some resources to a given directory.

 <copy todir="${live}" flatten="true">
  <resources>
    <file file="${test}/index.cfm" />
      <url url="http://www.andyjarrett.co.uk/andy/blog/index.cfm" />
     </resources>
 </copy>

Copies the two newest resources into a destination directory.

 <copy todir="${live}" flatten="true">
  <first count="2">
    <sort>
      <date xmlns="antlib:org.apache.tools.ant.types.resources.comparators" />
      <resources>
          <file file="${test}/file1.txt" />
          <file file="${test}/file2.txt" />
          <file file="${test}/file3.txt" />
          <url url="http://ant.apache.org/index.html" />
      </resources>
    </sort>
  </first>
</copy>

More resources:

I’m here, learning and working away. If you liked this content and want to keep me going, consider buying me a coffee. Your support keeps this site running and the coffee brewing! ☕️