1. 序章

ほとんどのプログラミング言語では、ファイル操作には多くの定型コードが必要です。 リソースの開閉からネストされたディレクトリの作成まで、説明的なコードを何行も書く必要があります。

特に小規模なプロジェクトやユーティリティでは、単純なファイルライブラリが大きな違いを生みます。 Ammonite-Opsは、ファイル操作を簡単にするScalaのライブラリであり、Ammoniteプロジェクトの一部です。

Ammonite-Opsは、アンモナイトスクリプトとして個別に使用することも、ライブラリの依存関係として大きなプロジェクトの他のライブラリと同様に追加することもできます。 このチュートリアルでは、Ammonite-Opsと、それを使用して日常のファイル操作をすばやく実行する方法について説明します。

2. 利点

Ammonite-Opsを使用する利点のいくつかは次のとおりです。

  • ボイラープレートコードは必要ありません
  • シンプルで簡潔な方法
  • シェルファイルコマンドに似ています

3. 依存

ライブラリをsbt依存関係として追加できます。

libraryDependencies += "com.lihaoyi" %% "ammonite-ops" % "2.4.0"

これで、ライブラリの使用を開始できます。 import ステートメントを使用すると、日常のすべての操作にアクセスできます。

import ammonite.ops._

4. ファイル操作

標準のファイル操作を見てみましょう。

4.1. パス参照の作成

Ammonite-OpsはPathで動作します。 これは、os-libライブラリのjava.nio.Pathの代替であり、その上にAmmonite-Opsが構築されています。 pwd メソッドを使用して、Path参照を作成できます。

val workingDir: os.Path = pwd / "base"

4.1. ディレクトリコンテンツの一覧表示

特定のディレクトリの内容を取得するには、 ls!メソッドを使用できます。

val list = ls! workingDir

これにより、baseディレクトリの下にあるすべてのファイルとディレクトリが返されます。 ファイルのみを取得するには、isFile関数を使用してフィルターを適用できます。

val onlyFiles = list.filter(_.isFile)

ls.rec メソッドを使用して、すべてのファイルとディレクトリのリストを再帰的に取得できます。

val recursiveList = ls.rec! workingDir

isDir isSymLink owner permits など、詳細を取得するために使用できる他の多くのメソッドがありますファイルについて。

4.2. ディレクトリの作成

メソッドmkdir!を使用して、ディレクトリを作成できます。

mkdir! pwd/"base"

ネストされたディレクトリを作成することもできます。それらがすでに存在するかどうかを確認する必要はありません。 存在しない場合はディレクトリを作成し、すでに存在する場合はディレクトリの作成をスキップします。

mkdir! pwd / "sub1" / "sub2" / "sub3"

4.3. ファイルとディレクトリをコピーする

ファイルやディレクトリをコピーする方法は複数あります。 いくつかの異なるシナリオを見てみましょう。

cpメソッドは、あるディレクトリの内容を別のパスにコピーします

cp pwd/"dir1" pwd/"dir2"

ディレクトリdir2は存在してはならないことに注意してください。 ディレクトリがすでに存在する場合、cpは例外をスローします

同様に、 cp.intoメソッドは、ディレクトリの内容を別のディレクトリにコピーします。 ターゲットディレクトリがすでに存在する場合は、例外がスローされます

cp.into(wd / "dir1", wd/"dir2")

cp.overメソッドはcp.intoメソッドに似ていますが、すでに存在する場合は内容を上書きします

cp.over(wd / "dir1", wd/"dir4")

4.4. ファイルとディレクトリを削除する

rm!メソッドを使用して、ファイルまたはディレクトリを簡単に削除できます。

rm! wd / "dir1"

ディレクトリを削除すると、その内容もすべて削除されます。

4.5. ファイルへの書き込み

write メソッドを使用すると、ファイルにコンテンツを簡単に書き込むことができます。 他のほとんどのファイルライブラリとは異なり、リソースを開いたり閉じたりする必要はありません。 単純なファイルを作成するには、ファイルへのパスとコンテンツを指定してwriteメソッドを呼び出します。

write(wd / "text" / "simple.txt", "This is a simple text file written using ammonite ops.")

これにより、パス wd /textにファイルsimple.txtが作成されます。 ターゲットディレクトリが存在しない場合は、例外がスローされます。 ただし、writeメソッドでパラメータcreateFolderstrueとして渡すと、必要なディレクトリが自動的に作成されます。

write(wd / "text" / "simple.txt", "This is a simple text file written using ammonite ops.", createFolders = true)

既存のファイルを上書きする場合は、write.overメソッドを使用できます。

write.over(wd / "text" / "simple.txt", "Overwrite contents", createFolders = true)

これにより、新しいファイルが作成され、そのファイルが存在しない場合はそのファイルに内容が書き込まれます。

上書きする代わりに、 append メソッドを使用して、既存のファイルにコンテンツを追加することもできます。

write.append(filePath, "Append new contents", createFolders = true)

4.6. ファイルの内容を読む

read メソッドを使用して、ファイルの内容を取得できます。

val filePath = wd / "s1" / "sub"/ "simple.txt"
val content: String = read(filePath)

デフォルトでは、readメソッドはファイルの内容をStringとして読み取ります。 read.bytes メソッドを使用して、コンテンツを Array[Byte]として読み取ることができます。

val byteContent: Array[Byte] = read.bytes(filePath)

また、ファイルの内容を1行ずつ読み取り、read.linesメソッドを使用してSeqとして結果を取得することもできます。

val lines: Seq[String] = read.lines(filePath)

4.7. ファイルとディレクトリの移動または名前の変更

mv メソッドを使用して、ファイルまたはディレクトリの名前を変更したり、移動したりできます。

mv(wd / "file.txt", wd / "myFile.txt")

mv.into メソッドを使用して、あるディレクトリから別の既存のディレクトリにファイルを移動することもできます。

mv.into(wd / "dir" / "file.txt", wd / "dir" / "subDir")

5. サブプロセスを生成する

Ammonite-Opsを使用して、Scalaコードからサブプロセスを生成することもできます。 これは、ユーティリティスクリプトの作成に非常に役立ちます。 ただし、これはコードが実行されているオペレーティングシステムによって異なります。

必要なメソッドをスコープに含めるには、importステートメントを追加する必要があります。

import ammonite.ops.ImplicitWd._

コードからOSレベルのコマンドを実行するために使用できる2つの異なる方法があります:%%%

メソッドはコマンドを実行し、出力をstdoutまたはstderrに書き込みます。  %% メソッドは、 CommandResult を返します。これには、コマンドのステータスに応じて、stderrまたはstdoutの結果が含まれます。

%("ls") //writes the ls output to stdout
val items: CommandResult = %%("ls") 
items.out.lines // returns List of files

6. 結論

この記事では、Ammonite-Opsライブラリを使用してファイル操作を簡単に実行する方法について説明しました。 スタンドアロンスクリプトまたは本格的なScalaプロジェクトのいずれかで使用できます。

いつものように、このチュートリアルで使用されるサンプルコードは、GitHubから入手できます。