File Input Output in Scala (original) (raw)
Published on 05 April 2019 (Updated: 15 May 2023)
Welcome to the File Input Output in Scala page! Here, you'll find the source code for this program as well as a description of how the program works.
Current Solution
import scala.io.Source
import java.io.{FileNotFoundException, IOException, File, FileOutputStream, PrintWriter}
object FileInputOutput {
// reading file then write to stdout
// write exception when fail
def readFromFile(filename: String) {
try {
val buffer = Source.fromFile(filename)
val lines = buffer.getLines
lines.foreach(println)
buffer.close
} catch {
case e: FileNotFoundException => println(s"File ${filename} does not exist.")
case e: IOException => println(s"I/O Exception when reading from ${filename}.")
case e: Throwable => println(s"Error <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi mathvariant="normal">.</mi><mi>g</mi><mi>e</mi><mi>t</mi><mi>M</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>w</mi><mi>h</mi><mi>e</mi><mi>n</mi><mi>r</mi><mi>e</mi><mi>a</mi><mi>d</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>f</mi><mi>r</mi><mi>o</mi><mi>m</mi></mrow><annotation encoding="application/x-tex">{e.getMessage} when reading from </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10903em;">tM</span><span class="mord mathnormal">ess</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">re</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">ro</span><span class="mord mathnormal">m</span></span></span></span>{filename}.")
}
}
// write to file
// stdout exception when fail
def writeToFile(filename: String, contents: String) {
try {
val writer = new PrintWriter(new File(filename))
writer.write(contents)
writer.close
} catch {
case e: FileNotFoundException => println(s"Cannot write into file ${filename}.")
case e: Throwable => println(s"Error <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi mathvariant="normal">.</mi><mi>g</mi><mi>e</mi><mi>t</mi><mi>M</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>w</mi><mi>h</mi><mi>e</mi><mi>n</mi><mi>w</mi><mi>r</mi><mi>i</mi><mi>t</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>t</mi><mi>o</mi><mi>f</mi><mi>i</mi><mi>l</mi><mi>e</mi></mrow><annotation encoding="application/x-tex">{e.getMessage} when writing to file </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10903em;">tM</span><span class="mord mathnormal">ess</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span></span></span></span>{filename}.")
}
}
def main(args: Array[String]) {
// write succesfully
writeToFile("output.txt", "I am a string.\nI am also a string.\nScala is fun!\n")
// read successfully
readFromFile("output.txt")
}
}
File Input Output in Scala was written by:
- rzuckerm
This article was written by:
- Jeremy Grifski
- rzuckerm
- Vee Ng
If you see anything you'd like to change or update, please consider contributing.
How to Implement the Solution
First of all let's look at the read / write functions as a whole, and their usages.
Read from a file
In many real world scenario, your program usually takes one of the two approaches when dealing with undeterministic I/O (also called side-effects): fail loudly or fail silently.
We want to fail loudly, i.e. throw exception, stop execution flow or output error as results, when the I/O is critical for the program to proceed.
// reading file then write to stdout
// write exception when fail
def readFromFile(filename: String) {
try {
val buffer = Source.fromFile(filename)
val lines = buffer.getLines
lines.foreach(println)
buffer.close
} catch {
case e: FileNotFoundException => println(s"File ${filename} does not exist.")
case e: IOException => println(s"I/O Exception when reading from ${filename}.")
case e: Throwable => println(s"Error <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi mathvariant="normal">.</mi><mi>g</mi><mi>e</mi><mi>t</mi><mi>M</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>w</mi><mi>h</mi><mi>e</mi><mi>n</mi><mi>r</mi><mi>e</mi><mi>a</mi><mi>d</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>f</mi><mi>r</mi><mi>o</mi><mi>m</mi></mrow><annotation encoding="application/x-tex">{e.getMessage} when reading from </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10903em;">tM</span><span class="mord mathnormal">ess</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">re</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">ro</span><span class="mord mathnormal">m</span></span></span></span>{filename}.")
}
}
Similar to many other language, scala.io.Source
provides the ability to get a file into a buffer-like instance, in our case BufferedSource
, using fromFile
. Source
is built-in with Java
exceptions to let us know what causes the failure in opening / reading the file.
Since we are dealing with a text file, we can simply use getLines
to convert BufferedSource
to a Iterator[String]
. We can also convert Iterator[String]
to a List[String]
or Array[String]
using .toList
and .toArray
respectively.
Iterator
interface allows us to traverse each line, using foreach
. The syntactic sugar lines.foreach(println)
you see here is short-hand for:
lines.foreach(line => println(line))
or
for (line <- lines) {
println(line)
}
After extracting the buffer, we close it with buffer.close
.
catch
block here demonstrate Scala's pattern matching feature. By default, all exceptions can be caught as a Throwable
. However we have the option to deal with specific exception (FileNotFoundException
or IOException
) separately.
Usage is simple:
readFromFile("output.txt")
Write to a file
Similar pattern for writing to files. Unlike read, which is usually at the beginning of some logic and having the input type determined gains us benefits, write is usually a void function with no return types, and called at the end of execution (result, log, etc.).
// write to file
// stdout exception when fail
def writeToFile(filename: String, contents: String) {
try {
val writer = new PrintWriter(new File(filename))
writer.write(contents)
writer.close
} catch {
case e: FileNotFoundException => println(s"Cannot write into file ${filename}.")
case e: Throwable => println(s"Error <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi mathvariant="normal">.</mi><mi>g</mi><mi>e</mi><mi>t</mi><mi>M</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>w</mi><mi>h</mi><mi>e</mi><mi>n</mi><mi>w</mi><mi>r</mi><mi>i</mi><mi>t</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>t</mi><mi>o</mi><mi>f</mi><mi>i</mi><mi>l</mi><mi>e</mi></mrow><annotation encoding="application/x-tex">{e.getMessage} when writing to file </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10903em;">tM</span><span class="mord mathnormal">ess</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span></span></span></span>{filename}.")
}
}
Usage is straightforward, simply call the function:
```scala
writeToFile("output.txt", "I am a string.\nI am also a string.\nScala is fun!\n")
How to Run the Solution
The source requires standard scala compiler and runtime: scalac
and scala
. Before running the program, make sure the files are in the same directory as the compiled .class
.
$ scalac FileInputOutput.scala
$ scala FileInputOutput