Deleting a file or directory

Deleting a file or directory may seem a trivial task and it often is, but it has some hidden quirks that Groovy may help you with. This recipe will enlist and give details about several methods to delete a file or a directory.

Getting ready

Let's assume that we have two java.io.File variables: one pointing to a normal file and another to a nonempty directory with several subdirectories in it. For example:

def dir = new File('./tmp1')
def file = new File('./tmp2/test.txt')

As you know from Java, the java.io.File class has a delete method and it works perfectly in many situations. But it will only delete a normal file or an empty directory. So, to delete a nonempty directory you need to write a recursive function in Java. Also, in most of the situations, the delete method will not throw any exceptions; it will just return false if it fails to delete a file or directory.

How to do it...

Let's explore several ways to delete things on the file system.

  1. To delete the nonempty directories, Groovy provides an extension method deleteDir in the java.io.File class. Let's try to delete our file and directory with both the delete and deleteDir methods and print the result:
    println file.deleteDir()
    println file.delete()
    println dir.delete()
    println dir.deleteDir()
  2. The previous code snippet should give the following output:
    false
    true
    false
    true

How it works...

The first method call returns false, because the given file is not a directory. The second one successfully deletes the file and returns true. The third one returns false because we try to delete a nonempty directory. The last one returns true, because we recursively delete the root folder and its subfolders with the Groovy's deleteDir method.

In order to ensure that a file or a directory is deleted, you always need to check the result of the delete or deleteDir method. In a scenario where several files or folders have to be deleted, you may end up with a lot of noisy conditional statements. Not pretty. An elegant solution to the issue posed above is possible by resorting to Groovy's metaprogramming features. The java.io.File class can be enhanced with a new method, safeDelete:

File.metaClass.safeDelete = {
  if (exists()) {
    if (isDirectory()) {
      if (!deleteDir()) {
        def msg = "Unable to delete a directory: ${name}"
        throw new IOException(msg)
      }
    } else {
      if (!delete()) {
        def msg = "Unable to delete a file: ${name}"
        throw new IOException(msg)
      }
    }
  }
}

Groovy metaprogramming and the metaClass object are discussed in more detail in Chapter 9, Metaprogramming and DSLs in Groovy. In short, the previous code adds a new method to the java.io.File class called safeDelete. The new method ensures that the file exists; then it checks if the File is a directory, and calls a recursive delete on it. If the File object points to a file, it calls a normal delete. If either the delete or deleteDir operations return false, the method throws an IOException.

After you have extended the java.io.File class, then you can simply call the method on any File instance:

file.safeDelete()
dir.safeDelete()

By using this method, you can avoid many conditional statements and implement simpler exception handling.

There's more...

One more way to manipulate files is by using Groovy's built-in Apache Ant support. Through the groovy.util.AntBuilder class, you can get access to all the common Ant tasks including the delete task.

def ant = new AntBuilder()
ant.delete(dir: file.absolutePath, failonerror:false)

Ant's file-handling capabilities are quite extended, especially when it comes to copying files around.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.86.18