Scala File I/O
File I/O lets your program read data from files and write results back to disk. Scala uses Java's I/O libraries under the hood, but also provides its own cleaner API through scala.io.Source. Always close resources after use, or better — use automatic resource management patterns to ensure cleanup even when errors occur.
Reading a File
import scala.io.Source
// Read entire file as a string
val content = Source.fromFile("data.txt").mkString
// Read line by line
val lines = Source.fromFile("data.txt").getLines().toList
// With explicit close
val source = Source.fromFile("data.txt")
try
val text = source.mkString
println(text)
finally
source.close()
File on disk: data.txt
│
▼ Source.fromFile("data.txt")
Source (lazy reader)
│
├── .mkString → entire file as one String
├── .getLines() → Iterator[String] (one per line)
└── .close() → release file handle
Safe File Reading with Try
import scala.io.Source
import scala.util.{Try, Using}
// Using (Scala 2.13+) — automatically closes the resource
def readFile(path: String): Try[String] =
Using(Source.fromFile(path))(_.mkString)
def readLines(path: String): Try[List[String]] =
Using(Source.fromFile(path))(_.getLines().toList)
readFile("config.txt") match
case scala.util.Success(content) => println(content)
case scala.util.Failure(ex) => println(s"Could not read file: ${ex.getMessage}")
Writing to a File
import java.io.{FileWriter, PrintWriter}
// Write a string to file
def writeFile(path: String, content: String): Unit =
val writer = new PrintWriter(new FileWriter(path))
try writer.write(content)
finally writer.close()
// Write lines to file
def writeLines(path: String, lines: List[String]): Unit =
val writer = new PrintWriter(path)
try lines.foreach(writer.println)
finally writer.close()
writeFile("output.txt", "Hello from Scala!")
writeLines("names.txt", List("Alice", "Bob", "Carol"))
Appending to a File
import java.io.{FileWriter, PrintWriter}
def appendToFile(path: String, line: String): Unit =
val writer = new PrintWriter(new FileWriter(path, true)) // true = append mode
try writer.println(line)
finally writer.close()
appendToFile("log.txt", "Server started at 09:00")
appendToFile("log.txt", "User logged in at 09:05")
appendToFile("log.txt", "Request processed at 09:06")
Reading CSV Data
import scala.io.Source
import scala.util.Using
case class Student(name: String, score: Int, grade: String)
def loadStudents(path: String): List[Student] =
Using(Source.fromFile(path)) { source =>
source.getLines()
.drop(1) // skip header row
.map(_.split(",").map(_.trim)) // split each line by comma
.collect {
case Array(name, score, grade) =>
Student(name, score.toInt, grade)
}
.toList
}.getOrElse(List.empty)
// Simulated: as if "students.csv" contained:
// Name,Score,Grade
// Alice,92,A
// Bob,78,B
// Carol,85,B
Writing CSV Data
import java.io.PrintWriter
def saveStudents(path: String, students: List[Student]): Unit =
val writer = new PrintWriter(path)
try
writer.println("Name,Score,Grade")
students.foreach { s =>
writer.println(s"${s.name},${s.score},${s.grade}")
}
finally
writer.close()
val students = List(
Student("Alice", 92, "A"),
Student("Bob", 78, "B"),
Student("Carol", 85, "B")
)
saveStudents("output_students.csv", students)
Using for Automatic Resource Management
scala.util.Using is Scala's equivalent of Java's try-with-resources. It automatically calls close() on the resource when the block ends, even if an exception occurs:
import scala.util.Using
import scala.io.Source
import java.io.PrintWriter
// Read with auto-close
val lines = Using(Source.fromFile("input.txt")) { src =>
src.getLines().toList
}
// Write with auto-close
Using(new PrintWriter("result.txt")) { writer =>
writer.println("Line 1")
writer.println("Line 2")
writer.println("Line 3")
}
// Use multiple resources together
val result = Using.Manager { use =>
val reader = use(Source.fromFile("input.txt"))
val writer = use(new PrintWriter("output.txt"))
reader.getLines().foreach(writer.println)
}
Checking File Existence
import java.io.File
val f = new File("data.txt")
println(f.exists()) // true or false
println(f.isFile()) // true if it's a file (not directory)
println(f.length()) // file size in bytes
println(f.getName()) // "data.txt"
println(f.getParent()) // parent directory path
// List files in a directory
val dir = new File(".")
dir.listFiles().filter(_.isFile).foreach { f =>
println(f.getName)
}
Reading from URL
import scala.io.Source
val url = "https://www.example.com"
val html = Source.fromURL(url).mkString
println(html.take(200)) // first 200 characters of the page
File I/O Summary
Task Code
─────────────────────────── ─────────────────────────────────────────
Read entire file Source.fromFile(path).mkString
Read lines Source.fromFile(path).getLines().toList
Safe read Using(Source.fromFile(path))(_.mkString)
Write file PrintWriter(path).println(content)
Append to file FileWriter(path, true) → PrintWriter
Check exists new File(path).exists()
Auto-close resource scala.util.Using { }
Always close file handles — unclosed files can cause data corruption, resource leaks, and OS-level errors. Prefer Using for any file operation so resources are guaranteed to close regardless of what happens inside the block.
