倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

Groovy JDK? It's GDK! (File 編3) 行処理

前回に引き続き、今回も GDK が java.io.File に追加している文字列関連のメソッドを見ていきます(目次)。 readLines() メソッドは各行を String オブジェクトとする、List<String> オブジェクトを返す「一括読み込み」メソッドです。 それ以外のメソッドは、Closure オブジェクトを引数にとり、各行に対して処理を行う「反復読み込み」メソッドです。 定義されているメソッドは以下の通り:

メソッド 返り値 since
一括読み込み readLines()
readLines(String cs)
List 1.0
1.6.8
反復読み込み eachLine(Closure c)
eachLine(int firstLine, Closure c)
splitEachLine(String regex, Closure c)
splitEachLine(Pattern p, Closure c)
filterLine(Writer w, Closure c)
filterLine(Closure c)
Object
Object
Object
Object
Object
Writable
1.5.5
1.5.7
1.5.5
1.6.8
1.0
1.0
反復読み込み
(文字セット指定)
eachLine(String cs, Closure c)
eachLine(String cs, int firstLine, Closure c)
splitEachLine(String regex, String cs, Closure c)
splitEachLine(Pattern p, String cs, Closure c)
filterLine(Writer w, String cs, Closure c)
filterLine(String cs, Closure c)
Object
Object
Object
Object
Object
Writable
1.6.8
  • cs は文字セット (character set) を指定する文字列です。 色を変えているのは見やすさのためだけです。
  • eachLine() の引数の Closure は、引数として「1つの String」もしくは「1つの String と 1 つの int」をとります。 String には行の内容が、int には行番号(1から始まる)が割り当てられます。
  • splitEachLine() の引数の Closure は引数として1つの(String の)java.util.List をとり、第1引数の正規表現にマッチする部分で分割された行の内容が割り当てられます。
  • filterLine() の引数の Closure は引数として1つの String をとり、行の内容が割り当てられます。 この Closure は boolean 型を返す必要があり、true の場合のみ読み取りを行います。

ではサンプルコード:

// ***** 準備 *****
def src = new File('source.txt')
src.text = // 文章は Groovy の HP より (http://groovy.codehaus.org/)
'''Groovy...
* is an agile and dynamic language for the Java Virtual Machine
* builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk
* makes modern programming features available to Java developers with almost-zero learning curve
* provides the ability to statically type check and statically compile your code for robustness and performance
* supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain
* makes writing shell and build scripts easy with its powerful processing primitives, OO abilities and an Ant DSL
* increases developer productivity by reducing scaffolding code when developing web, GUI, database or console applications
* simplifies testing by supporting unit testing and mocking out-of-the-box
* seamlessly integrates with all existing Java classes and libraries
* compiles straight to Java bytecode so you can use it anywhere you can use Java'''

def String head(String line){
    // 標準出力への結果が見やすくなるように処理。 本筋とは無関係っす。
    return line.replaceAll('[*]', 'Groovy')[0..<20] + '...'
}


// ***** 一括読み込み readLines() *****
assert src.readLines().size() == 11    // 行数

// ***** 反復読み込み1 eachLine(Closure), eachLine(int, Closure) *****
src.eachLine{ line, no ->  // no には行番号(1から始まる)が割り当てられる。 なくても OK。
    if('Groovy...' == line)return
    else println "$no) ${head(line)}"
}
// 出力結果
// 2) Groovy is an agile a...
// 3) Groovy builds upon t...
// ...
// 11) Groovy compiles stra...
println()

src.eachLine(0){ line, no ->    // 0 は行番号の初期値
    if(no == 0)return
    else println "${no}) ${head(line)}"
}
// 出力結果
// 1) Groovy is an agile a...
// 2) Groovy builds upon t...
// ...
// 10) Groovy compiles stra...
println()


// ***** 反復読み込み2 splitEachLine(Pattern, Closure) *****
src.splitEachLine(~/\s+/){ words ->  // 空文字列で分割。 words は List
    if(words.size() == 1)return
    println head(words.join('_'))
}
// 出力結果
// Groovy_is_an_agile_a...
// Groovy_builds_upon_t...
// ...
// Groovy_compiles_stra...
println()


// ***** 反復読み込み3 filterLine(Writer, Closure)、 filterLine(Closure) *****
def dest1 = new File('dest1.txt')
dest1.withWriter{ writer ->
    src.filterLine(writer){ it.size() > 20 }    // boolean を返す Closure。 true なら読み込み(writer へ書き出し)
}
// 出力結果
// * is an agile and dynamic language for the Java Virtual Machine
// * builds upon the strengths of Java but has additional power ...
// ...
// * compiles straight to Java bytecode so you can use it anywhere you can use Java
println()

def dest2 = new File('dest2.txt')
dest2 << src.filterLine('UTF-8'){ it.startsWith('*') }    // boolean を返す Closure。 true なら読み込み(dest2 へ書き出し)
// 出力結果
// * is an agile and dynamic language for the Java Virtual Machine
// * builds upon the strengths of Java but has additional power ...
// ...
// * compiles straight to Java bytecode so you can use it anywhere you can use Java

filterLine(Closure), filterLine(String, Closure) で返される Writable オブジェクトの扱い方が最初戸惑うかも。 まぁ、Writable が出てきたら << 演算子で何とかすればいいんじゃないかなぁ~

次回はファイル・ディレクトリの走査に関するメソッドを見ていく予定。

プログラミングGROOVY

プログラミングGROOVY

  • 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
  • 出版社/メーカー: 技術評論社
  • 発売日: 2011/07/06
  • メディア: 単行本(ソフトカバー)
  • 購入: 6人 クリック: 392回
  • この商品を含むブログ (155件) を見る
Groovyイン・アクション

Groovyイン・アクション

  • 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
  • 出版社/メーカー: 毎日コミュニケーションズ
  • 発売日: 2008/09/27
  • メディア: 単行本(ソフトカバー)
  • 購入: 5人 クリック: 146回
  • この商品を含むブログ (121件) を見る