In production code I recommend that you use a good “Files” library like Apache Commons IO, but if you want to create your own Scala FileUtils class, here’s some source code that can help you get started.
First, here’s some code for the FileUtils class (an object
, technically):
package io_examples.v1 import java.io.File //import io_examples.common.Control.using import scala.util.Try object FileUtils { def readTextFileAsString(filename: String): Try[String] = Try { val lines = using(io.Source.fromFile(filename)) { source => (for (line <- source.getLines) yield line).toList } lines.mkString("\n") } // TODO def copyFile(srcFile: File, destFile: File): Try[Boolean] = ??? def readFileToByteArray(file: File): Try[Array[Byte]] = ??? def readFileToString(file: File): Try[String] = ??? def readFileToString(file: File, encoding: String): Try[String] = ??? def readLines(file: File, encoding: String): Try[List[String]] = ??? def sizeOf(file: File): Try[BigInt] = ??? def sizeOfDirectory(directory: File): Try[BigInt] = ??? }
Here’s the using
method that’s referenced in that code:
object Control { def using[A <: { def close(): Unit }, B](resource: A)(f: A => B): B = try { f(resource) } finally { resource.close() } }
This code shows how you can use the readTextFileAsString
method:
import scala.util.{Failure, Success} object Driver extends App { val passwdFile = FileUtils.readTextFileAsString("/etc/passwd") passwdFile match { case Success(s) => println(s) case Failure(e) => println(e) } }
I prefer the Try/Success/Failure approach for working with files, because it’s easy to generate exceptions with File I/O code, and I like to be able to access the reason for the failure, which you can get if you have the exception. Conversely, if you use Option/Some/None, you can’t get to the failure reason.
More Scala File utility methods
While I’m in the neighborhood, here are some more Scala file utility methods that I just found in another old project:
import java.io.File import com.alvinalexander.annotations.impure object FileUtils { val SLASH = System.getProperty("file.separator") /** * Get a recursive listing of all files underneath the given directory. * from stackoverflow.com/questions/2637643/how-do-i-list-all-files-in-a-subdirectory-in-scala */ @impure def getRecursiveListOfFiles(dir: File): Seq[File] = { val fileArray = dir.listFiles fileArray ++ fileArray.filter(_.isDirectory).flatMap(getRecursiveListOfFiles) } @impure def getListOfFilesInDirectory(dirName: String): Seq[String] = { val dir = new File(dirName) dir.list } @impure def getListOfFilesInDirectoryAsOption (dirName: String): Option[Seq[String]] = { if (dirName==null || dirName.trim=="") { None } else { Some(getListOfFilesInDirectory(dirName)) } } }
If you want to use any of those methods, just delete the @impure
annotation, it isn’t important, just something I was playing with back in the day.
Some older code file-reading code
While I’m in the neighborhood, here’s some older Scala file-reading code. This code doesn’t use Try
, Option
, or anything similar, so you won’t want to use it in production code without changing it:
def readFileToString(canonFilename: String): String = { val bufferedSource = Source.fromFile(canonFilename) val fileContents = bufferedSource.getLines.mkString bufferedSource.close fileContents } def readFileToSeq(canonFilename: String): Seq[String] = { val bufferedSource = Source.fromFile(canonFilename) val fileContents = bufferedSource.getLines.toList bufferedSource.close fileContents }
this post is sponsored by my books: | |||
![]() #1 New Release |
![]() FP Best Seller |
![]() Learn Scala 3 |
![]() Learn FP Fast |