Reading a File in Groovy
1. Overview
In this quick tutorial, we’ll explore different ways of reading a file in Groovy.
Groovy provides convenient ways to handle files. We’ll concentrate on the File class which has some helper methods for reading files.
Let’s explore them one by one in the following sections.
2. Reading a File Line by Line
There are many Groovy IO methods like readLine and eachLine available for reading files line by line.
2.1. Using File.withReader
Let’s start with the http://docs.groovy-lang.org/next/html/groovy-jdk/java/io/File.html
For example, let’s read a file line by line and print each line. We’ll also return the number of lines:
int readFileLineByLine(String filePath) {
File file = new File(filePath)
def line, noOfLines = 0;
file.withReader { reader ->
while ((line = reader.readLine()) != null) {
println "${line}"
noOfLines++
}
}
return noOfLines
}
Let’s create a plain text file fileContent.txt with the following contents and use it for the testing:
Line 1 : Hello World!!!
Line 2 : This is a file content.
Line 3 : String content
Let’s test out our utility method:
def 'Should return number of lines in File given filePath' () {
given:
def filePath = "src/main/resources/fileContent.txt"
when:
def noOfLines = readFile.readFileLineByLine(filePath)
then:
noOfLines
noOfLines instanceof Integer
assert noOfLines, 3
}
The withReader method can also be used with a charset parameter like UTF-8 or ASCII to read encoded files. Let’s see an example:
new File("src/main/resources/utf8Content.html").withReader('UTF-8') { reader ->
def line
while ((line = reader.readLine()) != null) {
println "${line}"
}
}
2.2. Using File.eachLine
new File("src/main/resources/fileContent.txt").eachLine { line ->
println line
}
2.3. Using File.newInputStream with InputStream.eachLine
def is = new File("src/main/resources/fileContent.txt").newInputStream()
is.eachLine {
println it
}
is.close()
When we use the newInputStream method, we have to deal with closing the InputStream.
If we use the withInputStream method instead, it will handle closing the InputStream for us:
new File("src/main/resources/fileContent.txt").withInputStream { stream ->
stream.eachLine { line ->
println line
}
}
3. Reading a File into a List
3.1. Using File.readLines
Let’s have a quick look at an example that reads file content and returns a list of lines:
List<String> readFileInList(String filePath) {
File file = new File(filePath)
def lines = file.readLines()
return lines
}
Let’s write a quick test using fileContent.txt:
def 'Should return File Content in list of lines given filePath' () {
given:
def filePath = "src/main/resources/fileContent.txt"
when:
def lines = readFile.readFileInList(filePath)
then:
lines
lines instanceof List<String>
assert lines.size(), 3
}
3.2. Using File.collect
def list = new File("src/main/resources/fileContent.txt").collect {it}
4. Reading a File into a Single String
We can read an entire file into a single String simply by using the text property of the File class.
Let’s have a look at an example:
String readFileString(String filePath) {
File file = new File(filePath)
String fileContent = file.text
return fileContent
}
Let’s verify this with a unit test:
def 'Should return file content in string given filePath' () {
given:
def filePath = "src/main/resources/fileContent.txt"
when:
def fileContent = readFile.readFileString(filePath)
then:
fileContent
fileContent instanceof String
fileContent.contains("""Line 1 : Hello World!!!
Line 2 : This is a file content.
Line 3 : String content""")
}
4.2. Using File.getText
If we use the getTest(charset) method, we can read the content of an encoded file into a String by providing a charset parameter like UTF-8 or ASCII:
String readFileStringWithCharset(String filePath) {
File file = new File(filePath)
String utf8Content = file.getText("UTF-8")
return utf8Content
}
Let’s create an HTML file with UTF-8 content named utf8Content.html for the unit testing:
ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ
ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ
ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ
Let’s see the unit test:
def 'Should return UTF-8 encoded file content in string given filePath' () {
given:
def filePath = "src/main/resources/utf8Content.html"
when:
def encodedContent = readFile.readFileStringWithCharset(filePath)
then:
encodedContent
encodedContent instanceof String
}
5. Reading a Binary File with File.bytes
Groovy makes it easy to read non-text or binary files. By using the bytes property, we can get the contents of the File as a byte array:
byte[] readBinaryFile(String filePath) {
File file = new File(filePath)
byte[] binaryContent = file.bytes
return binaryContent
}
We’ll use a png image file, sample.png, with the following contents for the unit testing:
Let’s see the unit test:
def 'Should return binary file content in byte array given filePath' () {
given:
def filePath = "src/main/resources/sample.png"
when:
def binaryContent = readFile.readBinaryFile(filePath)
then:
binaryContent
binaryContent instanceof byte[]
binaryContent.length == 329
}
6. Conclusion
In this quick tutorial, we’ve seen different ways of reading a file in Groovy using various methods of the File class along with the BufferedReader and InputStream.
The complete source code of these implementations and unit test cases can be found in the GitHub project.