
- •Credits
- •About the Authors
- •About the Reviewers
- •www.PacktPub.com
- •Table of Contents
- •Preface
- •Introduction
- •Installing Groovy on Windows
- •Installing Groovy on Linux and OS X
- •Executing Groovy code from the command line
- •Using Groovy as a command-line text file editor
- •Running Groovy with invokedynamic support
- •Building Groovy from source
- •Managing multiple Groovy installations on Linux
- •Using groovysh to try out Groovy commands
- •Starting groovyConsole to execute Groovy snippets
- •Configuring Groovy in Eclipse
- •Configuring Groovy in IntelliJ IDEA
- •Introduction
- •Using Java classes from Groovy
- •Embedding Groovy into Java
- •Compiling Groovy code
- •Generating documentation for Groovy code
- •Introduction
- •Searching strings with regular expressions
- •Writing less verbose Java Beans with Groovy Beans
- •Inheriting constructors in Groovy classes
- •Defining code as data in Groovy
- •Defining data structures as code in Groovy
- •Implementing multiple inheritance in Groovy
- •Defining type-checking rules for dynamic code
- •Adding automatic logging to Groovy classes
- •Introduction
- •Reading from a file
- •Reading a text file line by line
- •Processing every word in a text file
- •Writing to a file
- •Replacing tabs with spaces in a text file
- •Deleting a file or directory
- •Walking through a directory recursively
- •Searching for files
- •Changing file attributes on Windows
- •Reading data from a ZIP file
- •Reading an Excel file
- •Extracting data from a PDF
- •Introduction
- •Reading XML using XmlSlurper
- •Reading XML using XmlParser
- •Reading XML content with namespaces
- •Searching in XML with GPath
- •Searching in XML with XPath
- •Constructing XML content
- •Modifying XML content
- •Sorting XML nodes
- •Serializing Groovy Beans to XML
- •Introduction
- •Parsing JSON messages with JsonSlurper
- •Constructing JSON messages with JsonBuilder
- •Modifying JSON messages
- •Validating JSON messages
- •Converting JSON message to XML
- •Converting JSON message to Groovy Bean
- •Using JSON to configure your scripts
- •Introduction
- •Creating a database table
- •Connecting to an SQL database
- •Modifying data in an SQL database
- •Calling a stored procedure
- •Reading BLOB/CLOB from a database
- •Building a simple ORM framework
- •Using Groovy to access Redis
- •Using Groovy to access MongoDB
- •Using Groovy to access Apache Cassandra
- •Introduction
- •Downloading content from the Internet
- •Executing an HTTP GET request
- •Executing an HTTP POST request
- •Constructing and modifying complex URLs
- •Issuing a REST request and parsing a response
- •Issuing a SOAP request and parsing a response
- •Consuming RSS and Atom feeds
- •Using basic authentication for web service security
- •Using OAuth for web service security
- •Introduction
- •Querying methods and properties
- •Dynamically extending classes with new methods
- •Overriding methods dynamically
- •Adding performance logging to methods
- •Adding transparent imports to a script
- •DSL for executing commands over SSH
- •DSL for generating reports from logfiles
- •Introduction
- •Processing collections concurrently
- •Downloading files concurrently
- •Splitting a large task into smaller parallel jobs
- •Running tasks in parallel and asynchronously
- •Using actors to build message-based concurrency
- •Using STM to atomically update fields
- •Using dataflow variables for lazy evaluation
- •Index

Chapter 4
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.
149
www.it-ebooks.info

Working with Files in Groovy
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)
150
www.it-ebooks.info

Chapter 4
Ant's file-handling capabilities are quite extended, especially when it comes to copying files around.
See also
ff Chapter 9, Metaprogramming and DSLs in Groovy
ff http://groovy.codehaus.org/Using+Ant+from+Groovy
ff http://groovy.codehaus.org/api/groovy/util/AntBuilder.html
Walking through a directory recursively
Hierarchical file systems are the way we store most of our data. Groovy can help to build code that needs to go through a dense forest of directory trees.
In this recipe, we will cover different ways of walking through a directory tree using Groovy I/O awesomeness.
Getting ready
Let's assume that we need to walk through the current working directory. We can define the currentDir variable of java.io.File type that points to it:
def currentDir = new File('.')
To test this recipe, you can use either a script file that you launch with the groovy command or the groovysh/groovyConsole prompt.
How to do it...
As you probably know, the java.io.File class already provides the list and listFiles methods that return a collection of first-level elements (files and directories) in a directory represented by a File object. Using a recursive function, you can easily traverse the subfolders found in the first-level folders.
1.However, Groovy already provides more concise methods that use recursion internally to traverse a directory. One of them is the eachFileRecurse method. It takes a closure as an input parameter, which is called for every file or directory entry that
is found:
currentDir.eachFileRecurse { File file -> println file.name
}
151
www.it-ebooks.info

Working with Files in Groovy
2.If you need to walk recursively only through the directories, then you can use the eachDirRecurse method instead:
currentDir.eachDirRecurse { File dir -> println dir.name
}
3.If you only need to go through the files, then you can pass an additional parameter to eachFileRecurse, which is a value of a groovy.io.FileType enumeration (you'll need to add an additional import at the beginning of your script or groovysh/ groovyConsole prompt):
import groovy.io.FileType
...
currentDir.eachFileRecurse(FileType.FILES) { File file -> println file.name
}
How it works...
The previous code recursively prints the names of all the files and/or directories in the current directory tree. The recursive walk performs a depth-first search. That means that when the search goes through a list of children and encounters a directory, then it goes (deeper) inside that directory first before returning to process the remaining children. The order in which files and directories are processed depends on the implementation of the file system.
There's more...
Groovy also adds the eachFile and eachDir methods to a java.io.File class that you can use to iterate through the first-level elements only (just like listFiles). As other eachmethods, they take a closure as an input parameter. You can use that to build a recursive function in a similar way as you would use it with the listFiles method. But instead of defining a separate function, you can also make use of Groovy's closure that is capable of creating a copy of itself with the help of the trampoline method:
currentDir.eachFile { File file -> println file.name
if (file.isDirectory()) { file.eachFile( trampoline() )
}
}
The code snippet above does exactly the same thing as the previous code examples. The "magic" trampoline method passes a copy of the parent closure to the nested eachFile call, a copy of the parent closure and makes it behave like a recursive function.
152
www.it-ebooks.info