Created
January 23, 2011 16:40
-
-
Save anonymous/792198 to your computer and use it in GitHub Desktop.
Multithreaded find files
This file contains hidden or 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
(ns find | |
(:gen-class)) | |
(import '(java.io File) | |
'(java.lang Boolean) | |
'(java.util.regex Pattern) | |
'(java.util.regex Matcher)) | |
(defn print-list [lst] | |
"Prints the list of items." | |
(loop [l lst] | |
(if (or (nil? l) (empty? l)) | |
nil | |
(do | |
(println (str (first l) " ")) | |
(recur (next l))))) | |
(println "")) | |
(defn join [col1 col2] | |
"Joins two collections." | |
(if (or (nil? col2) (empty? col2)) | |
col1 | |
(if (or (nil? col1) (empty? col1)) | |
col2 | |
(join (conj col1 (first col2)) (next col2))))) | |
(defn concat-dirs [base dir] | |
"Creates a string from the base dir and the specified dir | |
taking into account the slash-separator." | |
(if (or (nil? base) (nil? dir)) | |
nil | |
(if (.endsWith base File/separator) | |
(str base dir) | |
(str base File/separator dir)))) | |
(defn matcher [pattern] | |
"Returns a matcher function for comparing | |
the file name with the pattern." | |
(let [p (Pattern/compile pattern)] | |
(fn [fname] | |
(let [m (.matcher p fname)] | |
(.matches m))))) | |
(defn find-files [matcher-func directory] | |
"Searches in the current dir for other dirs and matching files. | |
The matched files collects into a vector. | |
Searches recursively in the other dirs." | |
(if (or (nil? directory) (nil? matcher-func)) | |
nil | |
(let [current (File. directory) | |
cur-list (seq (.list current)) | |
dirs (filter #(and (not (= % ".")) (not (= % ".."))) | |
(filter #(.isDirectory (File. (concat-dirs directory %))) cur-list)) | |
files (filter #(.isFile (File. (concat-dirs directory %))) cur-list) | |
found (future (vec (map #(concat-dirs directory %) | |
(filter #(matcher-func %) files))))] | |
(loop [d dirs | |
f []] | |
(if (or (nil? d) (empty? d)) | |
(join f @found) | |
(recur (next d) | |
(join f (find-files matcher-func | |
(concat-dirs directory (first d)))))))))) | |
(defn -main [& args] | |
"Parses the command line and starts searching." | |
(let [filename (first args) | |
directory (second args)] | |
(println (str "Searching in " directory " for " filename)) | |
(let [found-files (find-files (matcher filename) directory)] | |
(print-list found-files))) | |
(shutdown-agents) | |
(println "Finished.")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment