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().