ZIO 2: How to read a file and write its output to the console

As a brief example here today, the following Scala/ZIO source code shows one way to read a file using ZIO 2 and then print its output to the console:

//> using scala "3"
//> using lib "dev.zio::zio::2.0.22"
package zio_file_io

import java.io.{BufferedReader, FileReader}
import scala.util.{Try, Using}
import zio.*
import zio.Console.*

def readFile(filename: String): Try[Seq[String]] =
    Using(BufferedReader(FileReader(filename))) { reader =>
        Iterator.continually(reader.readLine())
                .takeWhile(_ != null)
                .toSeq
    }

def getRidOfUndesiredLines(lines: Seq[String]): Seq[String] =
    lines.takeWhile(!_.startsWith("#"))
         .takeWhile(_.trim != "")
         .map(_.trim)

object ZioReadFile extends ZIOAppDefault:

    val filename = "stocks.dat"

    val program = for
        linesFromFile: Seq[String] <- ZIO.fromTry(readFile(filename))
        cleanLines: Seq[String] = getRidOfUndesiredLines(linesFromFile)
    yield
        cleanLines

    override val run = program.flatMap { (lines: Seq[String]) =>
        ZIO.foreach(lines) { line =>
            Console.printLine(line)
        }
    }

No doubt I will find better ways to do this over time, but for today I’m using that to read a file of stock symbols whose contents look like this:

AAPL
GOOG
NVDA

The file may also have comments that begin with the # symbol and blank lines, so that’s why I do a little extra processing in there.

In summary, if you wanted to see one way to read a file with ZIO 2 and then write its output to the console, I hope this example helps.