Reputation: 14258
In clojure.java.io
, there is a io/resource
function but I think it just loads the resource of the current jar that is running. Is there a way to specify the .jar
file that the resource is in?
For example:
/path/to/abc.jar
abc.jar
when unzipped contains some/text/output.txt
in the root of the unzipped directoryoutput.txt
contains the string "The required text that I want."
I need functions that can do these operations:
(list-jar "/path/to/abc.jar" "some/text/")
;; => "output.txt"
(read-from-jar "/path/to/abc.jar" "some/text/output.txt")
;; => "The required text that I want"
Thanks in advance!
Upvotes: 1
Views: 1145
Reputation: 14258
From Ankur's comments, I managed to piece together the functions that I needed:
The java.util.jar.JarFile
object does the job.
you can call the method (.entries (Jarfile. a-path))
to give the list of files but instead of returning a tree structure:
i.e:
/dir-1 /file-1 /file-2 /dir-2 /file-3 /dir-3 /file-4
it returns an enumeration of filenames:
/dir-1/file-1, /dir-1/file-2, /dir-1/dir-2/file-3, /dir-1/dir-3/file-4
The following functions I needed are defined below:
(import java.util.jar.JarFile) (defn list-jar [jar-path inner-dir] (if-let [jar (JarFile. jar-path)] (let [inner-dir (if (and (not= "" inner-dir) (not= "/" (last inner-dir))) (str inner-dir "/") inner-dir) entries (enumeration-seq (.entries jar)) names (map (fn [x] (.getName x)) entries) snames (filter (fn [x] (= 0 (.indexOf x inner-dir))) names) fsnames (map #(subs % (count inner-dir)) snames)] fsnames))) (defn read-from-jar [jar-path inner-path] (if-let [jar (JarFile. jar-path)] (if-let [entry (.getJarEntry jar inner-path)] (slurp (.getInputStream jar entry)))))
(read-from-jar "/Users/Chris/.m2/repository/lein-newnew/lein-newnew/0.3.5/lein-newnew-0.3.5.jar" "leiningen/new.clj") ;=> "The list of built-in templates can be shown with `lein help new`....." (list-jar "/Users/Chris/.m2/repository/lein-newnew/lein-newnew/0.3.5/lein-newnew-0.3.5.jar" "leiningen") ;; => (new/app/core.clj new/app/project.clj .....)
Upvotes: 2