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 File.withReader method. It creates a new BufferedReader under the covers that we can use to read the contents using the readLine method.
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 using ReadFile.readFileLineByLine 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
We can also use the eachLine method:
new File("src/main/resources/fileContent.txt").eachLine { line ->
println line
}
2.3. Using File.newInputStream with InputStream.eachLine
Let’s see how we can use the InputStream with eachLine to read a file:
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
Sometimes we need to read the content of a file into a list of lines.
3.1. Using File.readLines
For this, we can use the readLines method which reads the file into a List of Strings.
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 using ReadFile.readFileInList 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
We can also read the file content into a List of Strings using the collect API:
def list = new File("src/main/resources/fileContent.txt").collect {it}
3.3. Using the as Operator
We can even leverage the as operator to read the contents of the file into a String array:
def array = new File("src/main/resources/fileContent.txt") as String[]
4. Reading a File into a Single String
4.1. Using File.text
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 using ReadFile.readFileString 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"].join("\r\n"))
}
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 using ReadFile.readFileStringWithCharset 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 using ReadFile.readBinaryFile 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.