Created
September 2, 2015 18:55
-
-
Save TheDIM47/8bfa2bbf80e791c00e73 to your computer and use it in GitHub Desktop.
Recursive file finder with Scala and Akka
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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