Skip to content
AgileLogics
5 min read

Working with Files

Prerequisites: Error handling: exceptions and Try

Scala uses Java's java.nio.file API for files, plus a few helpers.

Writing and reading

import java.nio.file.{Files, Path}
import scala.jdk.CollectionConverters.*

@main def files(): Unit =
  val path = Path.of("notes.txt")
  Files.writeString(path, "first line\nsecond line\n")
  Files.writeString(path, "third line\n", java.nio.file.StandardOpenOption.APPEND)

  val lines = Files.readAllLines(path).asScala.toList
  println(lines)
  println(Files.readString(path).length)
  println(Files.exists(path))
  Files.delete(path)
  println(Files.exists(path))
List(first line, second line, third line)
34
true
false

asScala (from scala.jdk.CollectionConverters) converts Java collections into Scala ones.

Reading safely with Using

For large files, read line by line with scala.io.Source, and make sure the file is closed with Using:

import scala.io.Source
import scala.util.Using
import java.nio.file.{Files, Path}

@main def readLog(): Unit =
  Files.writeString(Path.of("app.log"),
    "INFO start\nERROR db timeout\nINFO request\nERROR disk full\n")

  val errors = Using(Source.fromFile("app.log")) { source =>
    source.getLines().filter(_.startsWith("ERROR")).map(_.drop(6)).toList
  }
  println(errors)

  val missing = Using(Source.fromFile("missing.log"))(_.getLines().size)
  println(missing.isFailure)
Success(List(db timeout, disk full))
true

Using(resource)(f) runs f, closes the resource no matter what, and returns a Try — so a missing file becomes a Failure, not a crash.

Listing and walking directories

import java.nio.file.{Files, Path}
import scala.jdk.StreamConverters.*

@main def walk(): Unit =
  Files.createDirectories(Path.of("src/utils"))
  for name <- List("src/App.scala", "src/utils/Math.scala", "src/README.md") do
    Files.writeString(Path.of(name), "")

  val scalaFiles = Files.walk(Path.of("src")).toScala(List)
    .filter(_.toString.endsWith(".scala"))
    .map(_.getFileName.toString)
    .sorted
  println(scalaFiles)
List(App.scala, Math.scala)

The os-lib library offers a friendlier API for scripts: os.read(os.pwd / "notes.txt"), os.list(path), os.proc("git", "status").call().