ScalaのIOライブラリは何を使うのがいいのかなぁ、ということで前回はscalaz-effectを試してみたのですが、今回はsbtのIOライブラリを試してみました。sbtで使用されているものですが、単体のライブラリとしても使用することができます。
sbt-ioを使用するにはbuild.sbt
に以下の依存関係を追加します。
libraryDependencies += "org.scala-sbt" %% "io" % "1.0.0-M3"
sbt.io.IO
オブジェクトに様々な便利メソッドが用意されています。
import sbt.io._ import java.io._ // ファイルから文字列として読み込み val result1: String = IO.read(new File("build.sbt"), IO.utf8) // ファイルからバイト配列として読み込む val result2: Array[Byte] = IO.readBytes(new File("test.txt")) // ストリームからバイト配列として読み込み val result3: Array[Byte] = IO.readBytes(new FileInputStream("text.txt")) // ファイルから行ごとのリストとして読み込み val result4: List[String] = IO.readLines(new File("test.txt"), IO.utf8) // ファイルに文字列を書き込み IO.write(new File("test.txt"), "Hello World", IO.utf8) // ファイルにバイト配列を書き込み IO.write(new File("test.txt"), "Hello World".getBytes(IO.utf8)) // ファイルに行ごとのリストを書き込み IO.writeLines(new File("test.txt"), List("Hello", "World"), IO.utf8)
大きなファイルを読み込むときはIO.reader
でBufferedReader
を生成し、それをIO.foreachLine
やIO.foldLines
などのメソッドで1行ずつ処理することもできます。
IO.reader(new File("test.txt"), IO.utf8){ reader => IO.foreachLine(reader){ line => println(line) } }
入出力だけでなく、ファイル・ディレクトリ操作のためのメソッドもあります。
// ファイルがなければ作成 IO.touch("test.txt") // ファイルをコピー IO.copyFile(new File("test.txt"), new File("test.bak")) // ファイルを移動 IO.move(new File("test.txt"), new File("test.bak")) // ディレクトリをコピー IO.copyDirectory(new File("src"), new File("target")) // ファイルまたはディレクトリを削除 IO.delete(new File("test.txt"))
この他にもファイルを圧縮・展開するためのメソッドや、一時ファイル・一時ディレクトリを使用した処理を行うためのメソッド、URLのリソースをダウンロードして指定したファイルに保存するメソッドなど、様々な便利メソッドが用意されています。利用可能なメソッドはScaladocを参照するといいです。
なお、ローンパターン的なものはIO
内部では使用されているのですが、外部からは利用できないようになっています。自分でストリームをゴリゴリ触るようなケースではローンパターンが欲しくなると思うのでちょっと残念です。また、エラー処理に関しては例外が飛ぶようになっていますが、内部的にjava.io.File
のメソッドで処理しているようなものはメソッドの戻り値が無視されているケースもあり、厳密なエラーハンドリングが必要なケースでは使いにくいかもしれません。
sbt-ioは完璧とはいえないものの、便利かつ簡単に利用できるので、カジュアルな用途であればこれで十分なのではないかと思います。
追記:0.13.9ならローンパターン使えるそうです。
@takezoen ローンパターン、0.13.9だとpackage privateになってないので使えると思います(centralにはないので、たしかresolver必要だけど) https://t.co/hSXeYMY2Wp https://t.co/8xLJry3yLp
— Kenji Yoshida (@xuwei_k) 2016, 1月 24