- •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
Working with Files in Groovy
The leftShift operator is used again to append data to a stream. The stream object will be opened and closed automatically in a similar way to the withWriter method.
There's more...
You can also wrap file access using the withDataOutputStream and withObjectOutputStream methods. This gives you access to the java.
io.DataOutputStream and java.io.ObjectOutputStream instances
within a closure that allows you to write out primitive and serialized Java types respectively.
If you want to control the writer or stream instances yourself, you can use convenient constructor methods such as newWriter, newOutputStream, newDataOutputStream,
and newObjectOutputStream.
Many of the writing methods of java.io.File are also available in the java.io.Writer and java.io.OutputStream classes that allow using Groovy goodies for virtually any output target.
See also
ff Reading from a file
ff http://groovy.codehaus.org/groovy-jdk/java/io/File.html
ff http://groovy.codehaus.org/groovy-jdk/java/io/Writer.html
ff http://groovy.codehaus.org/groovy-jdk/java/io/OutputStream.html
ff http://groovy.codehaus.org/groovy-jdk/java/io/PrintWriter.html
ff http://groovy.codehaus.org/groovy-jdk/java/io/PrintStream.html
Replacing tabs with spaces in a text file
Searching and replacing file content is an often needed routine that can be automated with the help of Groovy scripts, one of which will be shown in this recipe.
Getting ready
Let's assume that we have an input.txt file that contains some tabulation characters.
We want to replace the tabulation characters with spaces and save the results into a output.txt file.
144
www.it-ebooks.info
Chapter 4
To perform any action on these files (similar to the Filtering a text file's content recipe), we need to create two instances of java.io.File objects:
def inputFile = new File('input.txt') def outputFile = new File('output.txt')
How to do it...
Let's go through several ways to achieve the desired result:
1.First of all, we will take advantage of the transformLine method available in the java.io.Reader class, as well as the withWriter and withReader methods that are described in more detail in the Writing to a file and Reading from a file recipes:
outputFile.withWriter { Writer writer -> inputFile.withReader { Reader reader ->
reader.transformLine(writer) { String line -> line.replaceAll('\t', ' ')
}
}
}
2. A more concise form of the above code snippet looks like this:
inputFile.withReader { reader -> reader.transformLine(outputFile.newWriter()) { line ->
line.replaceAll('\t', ' ')
}
}
3.Another way to do this is with the help of the getText and setText extension methods of java.io.File:
outputFile.text = inputFile.text.replaceAll('\t', ' ')
Although this approach is the shortest one, it has some complications, which we will describe in the next section.
How it works...
Groovy adds an extension method, transformLine, to the java.io.Reader class. We used this method in the first and second examples. The method takes two input parameters, a Writer and a Closure. The closure expects a String and it should return a transformed String back. The writer is used to output the transformed lines. This means that by
having a reader and a writer, we can use transformLine to perform a line-based data transformation.
145
www.it-ebooks.info
Working with Files in Groovy
Since the transformLine method automatically closes the writer, we can omit the outer method call to withWriter and just pass a new Writer instance to the transformLine method. That's what we've shown in the second example we just described.
The previous code snippet, of course, looks more concise; but this approach has one disadvantage. The whole file content will be loaded into the memory, and, in the case of a very large file, we are at risk of getting an OutOfMemoryError exception. With the first and second approaches, we don't risk incurring any memory problems.
You have to choose which approach is more appropriate based on your input file sizes.
There's more...
In a similar way as we used transformLine, you can also use the transformChar method to make character-based input transformations. For example, this code will transform a TAB character with a single space character:
inputFile.withReader { Reader reader -> reader.transformChar(outputFile.newWriter()) { String chr ->
chr == '\t' ? ' ' : chr
}
}
See also
The following recipes give an introduction to I/O operations in Groovy:
ff
ff
Reading from a file Writing to a file
Also, it's worth looking at what additional functionality Groovy offers in the java.io.Reader class:
ff http://groovy.codehaus.org/groovy-jdk/java/io/Reader.html
Filtering a text file's content
Filtering a text file's content is a rather common task. In this recipe, we will show how it can be easily achieved with Groovy.
146
www.it-ebooks.info
Chapter 4
Getting ready
Let's assume we want to filter out comment lines from a Bash script stored in the script.sh file and we want to save it into the new_script.sh file. First of all, we need to define two variables of the java.io.File type that point to our inputFile
and outputFile:
def inputFile = new File('script.sh')
def outputFile = new File('new_script.sh')
How to do it...
File filtering can be implemented in several ways:
1.We can make use of the closure-based methods (that is eachLine and withPrintWriter) that we have got familiar with in the Reading a text file line by line and Writing to a file recipes:
outputFile.withPrintWriter { writer -> inputFile.eachLine { line ->
if (!line.startsWith('#')) { writer.println(line)
}
}
}
2.Another way to achieve the same result is to use a filterLine method. It takes a Writer and a closure as input parameters. The closure gets a string line as an input and should return true or false depending on whether line is filtered in or out.
We can rewrite the original code snippet in the following way:
outputFile.withWriter { writer -> inputFile.filterLine(writer) { line ->
!line.startsWith('#')
}
}
3.Actually, the filterLine method also closes the given writer automatically. So, we can omit one closure from the previous code and just pass a new Writer instance to the method:
inputFile.filterLine(outputFile.newWriter()) { line -> !line.startsWith('#')
}
147
www.it-ebooks.info
Working with Files in Groovy
How it works...
In the first code example above, we have first called a method withPrintWriter to which we passed a closure in which we iterated through text lines with the help of the eachLine method. The inner closure passed to eachLine has access to both the writer and the line objects. Inside that closure, we added a simple conditional statement to write out only those lines that do not start with #.
In the second snippet, we passed a closure to the filterLine method. That closure gives you access to the line and expects to return a boolean that indicates whether that line should be written to the final output (writer) or not.
All code examples achieve the same result. The filtered Bash script should contain no comments after execution of the Groovy code demonstrated in the previous section.
There's more...
There is another overloaded version of the filterLine method that returns an instance
of groovy.lang.Writable. Writable has only one method that is, writeTo(java. io.Writer writer). It's a Groovy abstraction that allows postponing the content creation until it is actually streamed to the final output target. Instances of Writable can be used in most of the output operations such as print, write, append, and leftShift. That's why this filterLine version does not need any Writer. Taking it all into account, we can rewrite the previous code as a one-liner:
outputFile << inputFile.filterLine { !it.startsWith('#') }
The Writable result of the filterLine method is sent to outputFile with the help of the leftShift operator (you can read more about it in Writing to a file recipe). We also omitted the line variable and simply referred to Groovy's default it closure parameter. In this way, the code looks almost similar to an OS command; short and clear.
See also
Check the following recipes for some additional insights:
ff
ff
Reading a text file line by line Writing to a file
The following Groovydoc links may be of interest for the reader:
ff http://groovy.codehaus.org/api/groovy/lang/Writable.html ff http://groovy.codehaus.org/groovy-jdk/java/io/File.html
148
www.it-ebooks.info