Scala writing and reading data files
This post if from 2016, hope its helpful (it’s aimed at me when I’ve forgotten how)
Straight to the code again, and please see the previous post for an explanation deeper than I’ve given below - ie zero explanation.
// use an object just to create a terse example which is runnable
object WriteAndReadAFile extends App {
// Ensures the resource is closed
def using[A <: {def close() : Unit}, B](closeable: A)(f: A => B): B =
try f(closeable) finally closeable.close()
def readData(fileName: String): Try[List[(Int, Long, Int)]] = {
@tailrec
def readDataInputStream(acc: ArrayBuffer[(Int, Long, Int)], dis: DataInputStream): Try[List[(Int, Long, Int)]] = {
if (dis.available() == 0) Success(acc.toList)
else readDataInputStream(acc += Tuple3(dis.readInt(), dis.readLong, dis.readInt), dis)
}
def readIndexFileStream(fis: FileInputStream): Try[List[(Int, Long, Int)]] = {
for {
dis <- Try(new DataInputStream(fis))
listOfTuples <- readDataInputStream(ArrayBuffer.empty[(Int, Long, Int)], dis)
} yield listOfTuples
}
Try(using(new FileInputStream(fileName))(readIndexFileStream)).flatten
}
def writeData(fileName:String, data: List[(Int,Long,Int)]) :Try[Unit] = {
// Curried, so we can partially apply the data argument prior to calling using
def writeIndexRandomAccessFile(data:List[(Int, Long, Int)])(raf: RandomAccessFile): Try[Unit] = {
Try {
raf.seek(0)
data.foreach{case (seqNo, pos, len)=> {
raf.writeInt(seqNo)
raf.writeLong(pos)
raf.writeInt(len)
}}}
}
Try(using(new RandomAccessFile(fileName, "rw"))(writeIndexRandomAccessFile(data))).flatten
}
// inlining the testing
val fileName = "indexFile.idx"
writeData(fileName, List[(Int,Long,Int)]((1,0,50),(2,50,10),(3,60,5),(4,65,1))) match {
case Failure(ex) =>
println(s"Could not write file $fileName, detail ${ex.getClass.getName}:${ex.getMessage}")
case _ =>
}
readData(fileName) match {
case Success(data) => println(s"Data read: ${data.mkString(",")}")
case Failure(ex) =>
println(s"Could not read file $fileName, detail ${ex.getClass.getName}:${ex.getMessage}")
}
}
No explanation! This is a follow on from the previous post, so look there for notes.