Directories in Scala

Here’s the translation of the Go code example to Scala, formatted in Markdown suitable for Hugo:

Our first program demonstrates working with directories in the file system.

import java.io.File
import java.nio.file.{Files, Path, Paths}
import scala.jdk.CollectionConverters._

object Directories {
  def check(e: Option[Throwable]): Unit = {
    e.foreach(ex => throw ex)
  }

  def main(args: Array[String]): Unit = {
    // Create a new sub-directory in the current working directory.
    val subdir = new File("subdir")
    check(Option(subdir.mkdir()).filter(_ == false).map(_ => new Exception("Failed to create directory")))

    // When creating temporary directories, it's good practice to delete them when done.
    // We'll use a try-finally block to ensure cleanup.
    try {
      // Helper function to create a new empty file.
      def createEmptyFile(name: String): Unit = {
        check(Option(Files.write(Paths.get(name), Array.emptyByteArray)).map(_ => new Exception("Failed to create file")))
      }

      createEmptyFile("subdir/file1")

      // We can create a hierarchy of directories, including parents.
      val parentChild = new File("subdir/parent/child")
      check(Option(parentChild.mkdirs()).filter(_ == false).map(_ => new Exception("Failed to create directories")))

      createEmptyFile("subdir/parent/file2")
      createEmptyFile("subdir/parent/file3")
      createEmptyFile("subdir/parent/child/file4")

      // list directory contents
      println("Listing subdir/parent")
      Files.list(Paths.get("subdir/parent")).forEach { path =>
        println(s" ${path.getFileName} ${Files.isDirectory(path)}")
      }

      // Change the current working directory
      System.setProperty("user.dir", "subdir/parent/child")

      // Now we'll see the contents of subdir/parent/child when listing the current directory.
      println("Listing current directory (subdir/parent/child)")
      Files.list(Paths.get(".")).forEach { path =>
        println(s" ${path.getFileName} ${Files.isDirectory(path)}")
      }

      // Change back to where we started
      System.setProperty("user.dir", "../../..")

      // We can also visit a directory recursively, including all its sub-directories.
      println("Visiting subdir")
      Files.walkFileTree(Paths.get("subdir"), new SimpleFileVisitor[Path] {
        override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = {
          println(s" $file ${Files.isDirectory(file)}")
          FileVisitResult.CONTINUE
        }

        override def preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult = {
          println(s" $dir ${Files.isDirectory(dir)}")
          FileVisitResult.CONTINUE
        }
      })
    } finally {
      // Clean up by deleting the subdir and all its contents
      def deleteRecursively(file: File): Unit = {
        if (file.isDirectory) {
          file.listFiles.foreach(deleteRecursively)
        }
        file.delete()
      }
      deleteRecursively(new File("subdir"))
    }
  }
}

This Scala program demonstrates various operations with directories:

  1. Creating directories and files
  2. Listing directory contents
  3. Changing the current working directory
  4. Recursively walking through a directory structure

To run this program, save it as Directories.scala and use the Scala compiler and runtime:

$ scalac Directories.scala
$ scala Directories

The output will show the created directory structure and the results of listing and walking through the directories.

Note that Scala, being a JVM language, uses Java’s file I/O APIs. The java.nio.file package provides more modern and flexible file system operations compared to the older java.io.File class, although both are used in this example for demonstration purposes.

Remember to handle exceptions and clean up resources properly in real-world applications.