1. 概要

このクイックチュートリアルでは、Groovyでファイルを読み取るさまざまな方法について説明します。

Groovyは、ファイルを処理するための便利な方法を提供します。 ここでは、ファイルを読み取るためのいくつかのヘルパーメソッドを持つFileクラスに集中します。

次のセクションでそれらを1つずつ調べてみましょう。

2. ファイルを1行ずつ読み取る

readLineeachLineのように、ファイルを1行ずつ読み取るために使用できるGroovyIOメソッドは多数あります。

2.1. File.withReaderを使用する

File .withReaderメソッドから始めましょう。 readLineメソッドを使用してコンテンツを読み取るために使用できる新しいBufferedReaderを内部に作成します。

たとえば、ファイルを1行ずつ読み取り、各行を印刷してみましょう。 行数も返します。

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
}

次の内容のプレーンテキストファイルfileContent.txtを作成し、テストに使用してみましょう。

Line 1 : Hello World!!!
Line 2 : This is a file content.
Line 3 : String content

ユーティリティメソッドをテストしてみましょう。

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
}

withReaderメソッドは、UTF-8やASCIIなどの文字セットパラメーターとともに使用して、エンコードされたファイルを読み取ることもできます。 例を見てみましょう:

new File("src/main/resources/utf8Content.html").withReader('UTF-8') { reader ->
def line
    while ((line = reader.readLine()) != null) { 
        println "${line}"
    }
}

2.2. File.eachLineを使用する

eachLineメソッドを使用することもできます。

new File("src/main/resources/fileContent.txt").eachLine { line ->
    println line
}

2.3. File.newInputStreamInputStream.eachLineの使用

InputStreameachLineを使用してファイルを読み取る方法を見てみましょう。

def is = new File("src/main/resources/fileContent.txt").newInputStream()
is.eachLine { 
    println it
}
is.close()

newInputStreamメソッドを使用する場合、InputStreamを閉じる必要があります。

代わりにwithInputStreamメソッドを使用すると、InputStreamのクローズが処理されます。

new File("src/main/resources/fileContent.txt").withInputStream { stream ->
    stream.eachLine { line ->
        println line
    }
}

3. ファイルリストに読み込む

ファイルの内容を行のリストに読み込む必要がある場合があります。

3.1. File.readLinesを使用する

このために、ファイルをStringsListに読み込むreadLinesメソッドを使用できます。

ファイルの内容を読み取り、行のリストを返す例を簡単に見てみましょう。

List<String> readFileInList(String filePath) {
    File file = new File(filePath)
    def lines = file.readLines()
    return lines
}

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. File.collectを使用する

collect APIを使用して、ファイルの内容をStringsListに読み込むこともできます。

def list = new File("src/main/resources/fileContent.txt").collect {it}

3.3. as演算子の使用

as 演算子を利用して、ファイルの内容をString配列に読み込むこともできます。

def array = new File("src/main/resources/fileContent.txt") as String[]

4. ファイルを単一の文字列に読み込む

4.1. File.textを使用する

Fileクラスのtextプロパティを使用するだけで、ファイル全体を1つの文字列に読み込むことができます。

例を見てみましょう:

String readFileString(String filePath) {
    File file = new File(filePath)
    String fileContent = file.text
    return fileContent
}

ユニットテストでこれを確認しましょう:

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. File.getTextを使用する

getTest(charset)メソッドを使用する場合、UTF-8やASCIIなどのcharsetパラメーターを指定することで、エンコードされたファイルのコンテンツをStringに読み込むことができます。

String readFileStringWithCharset(String filePath) {
    File file = new File(filePath)
    String utf8Content = file.getText("UTF-8")
    return utf8Content
}

単体テスト用にutf8Content.htmlという名前のUTF-8コンテンツを含むHTMLファイルを作成しましょう。

ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ
ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ
ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ

ユニットテストを見てみましょう:

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. File.bytesを使用したバイナリファイルの読み取り

Groovyを使用すると、テキスト以外のファイルやバイナリファイルを簡単に読み取ることができます。 bytesプロパティを使用すると、ファイルの内容をバイト配列として取得できます

byte[] readBinaryFile(String filePath) {
    File file = new File(filePath)
    byte[] binaryContent = file.bytes
    return binaryContent
}

単体テストには、次の内容のpng画像ファイルsample.pngを使用します。

 

ユニットテストを見てみましょう:

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. 結論

このクイックチュートリアルでは、FileクラスのさまざまなメソッドとBufferedReaderおよびInputStreamを使用して、Groovyでファイルを読み取るさまざまな方法を見てきました。

これらの実装と単体テストケースの完全なソースコードは、GitHubプロジェクトにあります。