当前位置: 首页 > 知识库问答 >
问题:

惯用Clojure将资源从运行的jar复制到外部

越学义
2023-03-14

这似乎是一个经典问题,但我找不到任何关于它的“clojure方法”。

因此,我在参考资料/(leiningen项目)中有一个foo/目录。当jar'd/uberjar'd时,这个foo/目录放在jar的根目录下。由于jar中的文件在运行时可能在物理上不一致,所以不能使用基本复制函数将目录递归复制到外部世界。

Java世界存在几种解决方案(如何编写一个Java程序,它可以提取JAR文件并将其数据存储在指定的目录(位置)?如何从jar资源中提取目录(和子目录)?例如),但我没有找到任何现有的Clojure解决方案。作为一个初学者(包括Clojure和Java),我不确定如何将上述解决方案翻译成Clojure。从Java逐行翻译成CloJurishJavaInterop似乎不对。有没有一种“官方”的、符合习惯的方法来做到这一点?

请注意,我使用的是Raynes的fs实用程序库。似乎没有一个函数可以直接实现这一点,但也许有一些元素可以用来简化这个过程?(除了明显的基本io糖)

共有3个答案

东门翰
2023-03-14

在尝试了更多的方法并得到了#clojure的帮助后,我从我之前的第一个链接中找到了一个“类似于clojure-I-guess”的翻译:

(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)))))))))

我想我可以稍微整理一下(尤其是在.startswithbit周围),但至少它工作得很好。

姬墨竹
2023-03-14
(defn copy-resource! [resource-filename]
  (let [resource-file (io/resource resource-filename)
        tmp-file (io/file "/tmp" resource-filename)]
    (with-open [in (io/input-stream resource-file)] (io/copy in tmp-file))))

(copy-resource! "my-logo.png")
咸昀
2023-03-14

几个月前我编写了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/Resources"foo"))将提供您的foo目录的内容-如果您仅使用(cp/Resources"foo")类路径上的所有此类目录都会被找到,
  • 理论上,类路径上可以有多个具有相同路径的文件,这就是为什么函数返回多个uris;在我们的例子中,只有第一个感兴趣。
  • path总是以斜杠开始,所以要得到相对的斜杠,我们必须删除它。

也许这对你有帮助。

 类似资料:
  • 我想从jar复制一个文件。我要复制的文件将被复制到工作目录之外。我做了一些测试,我尝试的所有方法最终都是0字节的文件。 编辑:我希望通过程序复制文件,而不是手动复制。

  • 问题内容: 假设我的jar包“ com.test.io”中有一个名为test.txt的文件。 我将如何编写一个类来检索此文本文件,然后将内容复制到文件系统上的新文件中? 问题答案: 假设jar在您的类路径中:

  • 我已经尝试了很多方法,并遵循了几个在线说明,比如这个-Eclipse导出的Runnable JAR不显示图像,但到目前为止,没有成功。 我有一个非常简单的程序,读取一个文本文件(test.txt),并将其内容打印到标准输出。我正在使用Eclipse。这是我所做的- 我将文本文件放入名为“资源”的文件夹中 任何帮助都将不胜感激。 附录:这是代码。 }

  • 问题内容: 我有一些可怕的行为。我有以下Maven配置: 这将创建包含所有类的JAR文件,但我在类路径中有一些资源也应包括在内。如果我将参数放在阶段的前面,那么我的所有资源都会包括在内。如果我使用运行Maven ,则不包含任何资源。我的资源位于(不是通常的目录)下。 问题答案: 目标配置中未正确定义资源的源目录。同样,outputDirectory元素将资源放置在dir中,默认情况下将其打包。试试

  • 我有一些可怕的比目鱼。我有以下Maven配置: 这创建了包含所有类的JAR fie,但我在类路径中有一些资源也应该包括在内。如果我将参数留在phase前面,那么我的所有资源都包括在内了。如果我使用运行maven,则不包含任何资源。我的资源在(不是通常的目录)下。

  • 我花了好几个小时寻找答案,但我还是想不出答案,我正试图将包含我正在处理的游戏的所有图像和数据文件的资源文件夹从运行的jar中复制到e:/program files/mtd中/当我从eclipse中运行它时,它工作得很好,但当我导出jar并尝试它时,我得到了NoSuchFileException