Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 8435

ScalaでZIPファイルを簡単に扱うならos-libが便利そう - Lambdaカクテル

$
0
0

会社では定期的にScalaの新たなトピックを確認したり共有したりする会をやっている。そこでScalaのRedditを見ていると、os-libのバージョンアップが知らされていた。

見ると最近のバージョンではos-libはZIPを扱えるようになっていた。APIも便利そうなので紹介する。

os-libとは

そもそもos-libとは何かというと、lihaoyiさんという方が作っているScalaのライブラリで、ファイル操作やプロセス操作といったOS寄りのちょっとした操作を集めたユーティリティだ。

github.com

例えばコマンドを指定してプロセスを起動し、その標準出力をストリーミング形式で得るとか、ファイルを開いたり削除したり、一時ファイルを用意したりといった、シェルスクリプト的なおなじみの操作が用意されていて、しかもそのAPIがとても使いやすい。

val wd = os.pwd
os.write(wd/"file.txt", "hello") // カレントディレクトリの"file.txt"に、"hello"を書き込む

os-lib 0.11.0

os-lib 0.11.0で、ZIPファイルへのサポートが追加された。

github.com

利用できるようになった主要なAPIを紹介する:

os.zip: ZIPファイルを作成する / 既存のZIPファイルに追加する

既存のファイルをZIPファイルに入れられる。

//> using scala 3.5.0//> using deps "com.lihaoyi::os-lib:0.11.1"val wd = os.pwd
val file1 = wd / "file1.txt"val file2 = wd / "file2.txt"val file3 = wd / "file3.txt"

os.write.over(file1, "Hello World!")
os.write.over(file2, "Good World!")
os.write.over(file3, "Nice World!")

os.zip(wd / "zipfile.zip", Seq(file1, file2, file3), preserveMtimes = true)

os.zip.stream: ZIPファイルを作成するがファイルではなくストリームに出力する

os.write.outputStreamなどと組み合わせられる。

//> using scala 3.5.0//> using deps "com.lihaoyi::os-lib:0.11.1"val wd = os.pwd
val file1 = wd / "file1.txt"val file2 = wd / "file2.txt"val file3 = wd / "file3.txt"

os.write.over(file1, "Hello World!")
os.write.over(file2, "Good World!")
os.write.over(file3, "Nice World!")

val stream = os.zip.stream(Seq(file1, file2, file3), preserveMtimes = true)
val zipFileStream = os.write.outputStream(wd / "files.zip")
stream.writeBytesTo(zipFileStream)
zipFileStream.close()

os.unzip: ZIPファイルをディスク上に解凍する

excludePatternsincludePatternsを使って出力を制御できるのが便利。この例ではfile2.txtを除いてfilesディレクトリに解凍している(ディレクトリは自動的に生えてくるようだ)。

//> using scala 3.5.0//> using deps "com.lihaoyi::os-lib:0.11.1"val wd = os.pwd
val zip = wd / "files.zip"

os.unzip(zip, wd / "files", excludePatterns = Seq("file2.txt".r.anchored))

os.unzip.stream: ZIPファイルをjava.io.InputStreamからディスク上に出力する

これはos.zip.streamと勝手は同じなので省略。

os.unzip.list: ZIPファイルの内容をリストアップする

地味に便利な機能としてリストアップ機能がついている。

//> using scala 3.5.0//> using deps "com.lihaoyi::os-lib:0.11.1"val wd = os.pwd
val zip = wd / "files.zip"

println(os.unzip.list(zip).toSeq) // => Vector(file1.txt, file2.txt, file3.txt)

os.zip.open: ZIPファイルをjava.nio.file.FileSystemとして開き、os.Pathを返して利用できるようにする

これも結構便利そう。あたかもファイルシステムの上にあるように見えるので、直接ファイルの中身を見たり書いたりできるようになる。

//> using scala 3.5.0//> using deps "com.lihaoyi::os-lib:0.11.1"val wd = os.pwd
val zip = wd / "files.zip"val zipfilesystem = os.zip.open(zip)

try
  println(os.read(zipfilesystem / "file1.txt")) // Hello, World!finally
  zipfilesystem.close()

番外: os.unzip.streamRaw これは内部API

内部ストリームを露出するAPIも用意されているが、これはどちらかといえばパワーユーザ向けだろう。

まとめ

os-libでZIPファイルを扱えるようになるとできることの幅がけっこう広がる。手でzipを呼び出す必要がないのだ。この調子でgzipとかtarを扱えると嬉しいけれど、さすがにそこまでやるくらいならコマンドを呼び出したほうがよさそうだ。


Viewing all articles
Browse latest Browse all 8435

Trending Articles