Reading Files in Scala Here’s the translation of the Go code for reading files to Scala, with explanations in Markdown format suitable for Hugo:
import scala.io.Source
import java.io. { File , FileInputStream , RandomAccessFile }
import java.nio.file. { Files , Paths }
// Reading files is a common task in many Scala programs.
// Let's look at some examples of reading files.
// This helper function will streamline our error handling
def check [ T ]( expr : => T ) : T =
try {
expr
} catch {
case e : Exception => throw e
}
// Let's start with the main function
@main def readingFiles () : Unit = {
// Perhaps the most basic file reading task is
// slurping a file's entire contents into memory.
val dat = check ( Files . readAllBytes ( Paths . get ( "/tmp/dat" )))
print ( new String ( dat ))
// You'll often want more control over how and what
// parts of a file are read. For these tasks, we can use
// various Scala and Java APIs.
// Read some bytes from the beginning of the file.
// Allow up to 5 to be read but also note how many
// actually were read.
val fis = new FileInputStream ( "/tmp/dat" )
val b1 = new Array [ Byte ]( 5 )
val n1 = check ( fis . read ( b1 ))
println ( s" $n1 bytes: ${ new String ( b1 , 0 , n1 ) } " )
// You can also seek to a known location in the file
// and read from there using RandomAccessFile.
val raf = new RandomAccessFile ( "/tmp/dat" , "r" )
check ( raf . seek ( 6 ))
val b2 = new Array [ Byte ]( 2 )
val n2 = check ( raf . read ( b2 ))
println ( s" $n2 bytes @ ${ raf . getFilePointer - n2 } : ${ new String ( b2 , 0 , n2 ) } " )
// Seeking relative to the current position
check ( raf . seek ( raf . getFilePointer + 4 ))
// and relative to the end of the file.
check ( raf . seek ( raf . length - 10 ))
// The Source from scala.io provides a convenient way
// to read files line by line or as a whole.
val source = Source . fromFile ( "/tmp/dat" )
val lines = source . getLines (). toList
println ( s"Read ${ lines . length } lines" )
source . close ()
// There is no built-in rewind, but we can
// accomplish this by seeking to the start of the file.
check ( raf . seek ( 0 ))
// We can use BufferedSource for efficient reading
// of small chunks.
val bufferedSource = Source . fromFile ( "/tmp/dat" )
val firstFive = bufferedSource . take ( 5 ). mkString
println ( s"5 bytes: $firstFive " )
bufferedSource . close ()
// Close the file handles when you're done
fis . close ()
raf . close ()
}
To run this program:
$ echo "hello" > /tmp/dat
$ echo "scala" >> /tmp/dat
$ scala reading-files.scala
hello
scala
5 bytes: hello
2 bytes @ 6: sc
Read 2 lines
5 bytes: hello
This Scala code demonstrates various ways to read files, including reading entire files, reading specific bytes, seeking to positions in files, and using buffered readers. It uses a combination of Java’s file I/O classes and Scala’s Source
for different reading operations.
Next, we’ll look at writing files.