Skip to content

Instantly share code, notes, and snippets.

@TheDIM47
Created September 2, 2015 18:55
Show Gist options
  • Save TheDIM47/8bfa2bbf80e791c00e73 to your computer and use it in GitHub Desktop.
Save TheDIM47/8bfa2bbf80e791c00e73 to your computer and use it in GitHub Desktop.
Recursive file finder with Scala and Akka
package fastlookup
import java.io.File
import akka.actor._
object FileFinder {
case class Scan(val dir: File, val name: String)
case class Found(val file: File)
case class Find(val name: String)
case object Done
def props(manager: ActorRef, dir: File): Props = Props(new FileFinder(manager, dir))
}
object FileManager {
def props(root: File): Props = Props(new FileManager())
}
import FileFinder._
/**
* Non-recursive search for file or directory with "name" in single directory
* Handles:
* Find(name) - search for name in directory
* Send:
* Found(file) - file or directory found (case-insensitive)
* Scan(dir, name) - tell to FileManager to start search in sub-directory
* Done - directory scan complete
* @param manager search manager (parent)
* @param dir directory to search for
*/
class FileFinder(manager: ActorRef, dir: File) extends Actor {
def receive: Receive = {
case Find(name) =>
val files = dir.listFiles()
files.foreach(f => {
if (f.getName.equalsIgnoreCase(name)) {
manager ! Found(f)
}
if (f.isDirectory && !(f.getName == "." || f.getName == "..")) {
manager ! Scan(f, name)
}
})
manager ! Done
}
}
/**
* Manage set of FileFinder(s) and stop system when done (no more FileFinders)
* Handles:
* Scan(dir, name) - start search for name in specified directory
* Found(file) - file or directory
* Done - FileFinder finished
*/
class FileManager extends Actor {
var subs = Set.empty[ActorRef]
def receive: Receive = {
case Scan(dir, name) =>
val sub = context.actorOf(Props(classOf[FileFinder], self, dir))
subs += sub
sub ! Find(name)
case Found(file) =>
println(s"$file")
case Done =>
sender ! PoisonPill
subs -= sender
if (subs.isEmpty) context.system .shutdown
}
}
object FastLookup extends App {
if (args.length == 0) {
println("Usage: scala FastLookup.jar [start] <filename>")
} else {
val startDir = new File(if (args.length == 1) System.getProperty("user.dir") else args(0))
val fileToFind = if (args.length == 1) args(0) else args(1)
if (startDir.exists) {
if (startDir.isDirectory) {
val system = ActorSystem("FastLookup")
val app = system.actorOf(Props(classOf[FileManager]), "fast-lookup")
app ! Scan(startDir, fileToFind)
} else {
println(s"$startDir is NOT directory")
}
} else {
println(s"$startDir does NOT exists")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment