Groovy makes dealing with files a very pleasant business, thanks to a number of helper methods that work with standard Java's Reader
and Writer
, InputStream
and OutputStream
and File
classes.
In this recipe, we are going to look at the options available for reading a file in Groovy and accessing its content, mainly through the Groovy-enhanced File
class.
Let's assume we have a script that defines the following java.io.File
object:
def file = new File('poem.txt')
Of course, in order to be read, the poem.txt
file needs to exist in the same directory where our script is.
Let's explore some different ways to read the content of the
poem.txt
file.
java.lang.String
, you can use the getText
method provided by the Groovy JDK extension:String textContent = file.text
file.text
is equivalent to file.getText
, thanks to Groovy's special property getter handling syntax.
getBytes
method:byte[] binaryContent = file.bytes
withReader
method, which takes a closure as an input parameter:file.withReader { Reader reader -> def firstLine = reader.readLine() println firstLine }
withInputStream
method, which is similar to withReader
with the exception that the closure operates on a java.io.BufferedInputStream
instance:file.withInputStream { InputStream stream -> def firstByte = stream.read() println firstByte }
The getText
method displayed in step 1 can also be called by passing the charset
name, in order to specify the character encoding:
String textContent = file.getText('UTF-8')
The
withReader
method in step 3 is an example of how Groovy can make the code much more concise and unceremonious. In Java, readers and writers have to be explicitly closed after we finish with them. Groovy has several with...
methods for File
, URL
, streams, readers and writers, where ...
is the name of the stream, reader or writer class. We pass a closure to these methods and Groovy makes sure all streams, readers and writers are closed correctly, even if exceptions are thrown in the closure (Java 7 now has a similar feature via the java.lang.AutoCloseable
interface). The withReader
method creates a new java.io.BufferedReader
instance for the given file and passes the reader into the closure. It also ensures that the reader object gets closed after the method returns.
To get even more control, you can just use the newReader
method to get the reader
:
Reader reader = file.newReader()
Or the newInputStream
method to get the stream
:
InputStream stream = file.newInputStream()
Naturally, that means that you need to manually control the resource life cycle and close them properly.
The Groovy's extensions for java.io.File
also offer methods to create standard Java input streams. You can use newDataInputStream
or newObjectInputStream
to create streams for reading Java primitives and serialized Java objects. To get those streams automatically closed you can also use the withDataInputStream
and withObjectInputStream
methods.
All the methods described above shorten your path to reading a file's content compared to what you would need in pure Java.
Additionally, many of the methods (for example, getText
, getBytes
, and others described in later recipes) that we find on java.io.File
are also available in java.io.Reader
and java.io.InputStream
Groovy extensions.