The beginning of a Scala "FileUtils" class

By Alvin Alexander. Last updated: November 21, 2019

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
}
alvinalexander.com
is owned and operated by
Valley Programming, LLC

In regards to links to Amazon.com, As an Amazon Associate
I (Valley Programming, LLC) earn from qualifying purchases

This website uses cookies: learn more

AltStyle によって変換されたページ (->オリジナル) /