Java – an idiomatic clojure used to copy resources from the run jar to the outside
This seems to be a classic question, but I can't find any "clojure way" about it
So I have a foo / directory in resources / (leiningen project) When jar'd / uberjar'd, the foo / directory is placed in the root directory of jar Because the files in the jar may not be physically consistent at run time, you cannot use the basic copy function to recursively copy directories to the outside world
There are several solutions for the Java World (for example, how to write a java program which can extract a jar file and store its data in specified directory (location)? And how to extract directory (and sub directories) from jar resource, But I didn't find any existing clojure solution As a beginner (including clojure and Java), I'm not sure how to convert the above solution to clojure It does not seem correct to translate word for word from Java to clojurish Java interop Is there an "official" clojure idiomatic way to do this?
Please note that I am using Raynes FS utility library There seems to be no function to directly perform this function, but maybe I can use some elements to simplify the process? (except for obvious basic IO sugar)
Solution
A few months ago I wrote cpath - clj, which lists the resources on the classpath by URI You can then try the following:
(require '[cpath-clj.core :as cp] '[clojure.java.io :as io]) (doseq [[path uris] (cp/resources (io/resource "foo")) :let [uri (first uris) relative-path (subs path 1) output-file (io/file output-directory relative-path)]] (with-open [in (io/input-stream uri)] (io/copy in output-file)))
Since the library does not remember this use case, there are some juggling:
>(CP / resources (IO / resource "foo")) will provide you with the contents of the foo Directory - if you only use (CP / resources "foo"), you will find all such directories on the classpath, > theoretically, there can be multiple files with the same path on the classpath, which is why the function returns multiple URIs; In our example, only the first one is interested. > Path always starts with a slash, so to get a relative path, we must delete it
Maybe it will help you