习惯性的Clojure将资源从运行的jar复制到外部
这似乎是一个古典问题,但我无法找到任何关于它的“clojure方式”。
所以,我在资源/(leiningen项目)中有一个foo /目录。 当jar'd / uberjar'd,这个foo /目录放在jar的根目录下。 由于jar内的文件在运行时可能并不一致,因此不能使用基本复制功能将目录递归复制到外部世界。
存在几种Java世界的解决方案(如何编写一个可以提取JAR文件并将其数据存储在指定目录(位置)的Java程序?以及如何从jar资源中提取目录(和子目录)?例如),但我没有找到任何现有的Clojure解决方案。 作为初学者(包括Clojure和Java),我不确定如何将以上解决方案转换为Clojure。 从字面上逐行翻译Java到Clojurish Java Interop似乎不太合适。 是否有一种“官方”,clojure-idiomatic的方式来做到这一点?
请注意,我正在使用Raynes的fs公用程序库。 似乎没有直接执行此操作的功能,但是可能有一些元素可用于简化此过程? (除了明显的基本碘糖)
几个月前我写了cpath-clj,它将通过URI列出类路径中的资源。 您可以尝试以下操作:
(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)))
由于图书馆没有考虑到这个用例,所以有一些杂耍正在进行:
(cp/resources (io/resource "foo"))
会给你的内容foo
目录-如果你只有使用(cp/resources "foo")
在类路径上的所有这样的目录会被发现, path
可能有多个具有相同path
文件,这就是为什么该函数返回多个uris
; 在我们的案例中,只有第一个是有趣的。 path
总是以斜杠开始,所以为了获得相对的path
,我们必须删除它。 也许这对你有帮助。
我不知道惯用的部分,但资源目录中的文件可以用这种方式列出
(defn list-resource
[resource-dir]
(let [resource (io/file (io/resource resource-dir))]
(file-seq resource)))
并且将资源中的目录foo中的文件复制到当前路径就像
(io/copy (io/file (io/resource "foo/test.txt")) (io/file "test.txt"))
结合这两者,你应该能够写出一个递归函数来完成你所要求的
在尝试了更多并从#clojure获得帮助之后,我从我以前的第一个链接中找到了一种“巧妙的猜测”翻译:
(ns my-ns
(:require [me.raynes.fs :as f])
(:import [java.util.jar JarFile JarEntry]))
(defn extract-dir-from-jar
"Takes the string path of a jar, a dir name inside that jar and a destination
dir, and copies the from dir to the to dir."
[^String jar-dir from to]
(let [jar (JarFile. jar-dir)]
(doseq [^JarEntry file (enumeration-seq (.entries jar))]
(if (.startsWith (.getName file) from)
(let [f (f/file to (.getName file))]
(if (.isDirectory file)
(f/mkdir f)
(do (f/mkdirs (f/parent f))
(with-open [is (.getInputStream jar file)
os (io/output-stream f)]
(io/copy is os)))))))))
我想我可以稍微整理一下(特别是围绕.startsWith位),但至少可以完美地工作。
链接地址: http://www.djcxy.com/p/83879.html上一篇: Idiomatic Clojure to copy resources from running jar to outside
下一篇: UnsatisfiedLinkError (com.esri.core.runtime.LicenseImpl.nativeIsClientIdValid)