gpt4 book ai didi

java - 从外部 clojar 导入/使用资源

转载 作者:行者123 更新时间:2023-11-30 07:00:09 26 4
gpt4 key购买 nike

我想做的是将一个大文件(一个 MIDI soundfont)打包到一个独立的 Maven 存储库/clojar 中,然后能够以编程方式将其拉下来并从一个单独的项目中使用它。这个看似简单的任务被证明比我预期的要复杂。

理想的情况是,如果有一种方法可以直接访问这些资源,或者将它们公开为公共(public)变量或其他方式。这是我尝试的第一件事——我做了这样的事情:

(ns midi.soundfont.fluid-r3
(:require [clojure.java.io :as io]))

(def sf2
(io/file (io/resource "fluid-r3.sf2")))

但是,我遇到的问题是 io/resource 只能在当前类路径上找到资源文件。一旦我尝试从另一个项目(或 REPL)请求这个命名空间,我得到:

java.lang.IllegalArgumentException: Not a file: jar:file:/Users/dave/.m2/repository/midi/soundfont/fluid-r3/midi.soundfont.fluid-r3/0.1.0/midi.soundfont.fluid-r3-0.1.0.jar!/fluid-r3.sf2

如果无法直接访问资源,我会很高兴有一个解决方案,该解决方案涉及将文件复制到文件系统中的某个路径。我也尝试过这个,但是当我尝试从另一个项目运行“将文件复制到文件系统”方法时遇到了同样的问题——io/resource 仍然无法找到文件因为它不在当前类路径中。

我发现了之前在 SO 上提出的类似问题,例如:

但是,这些解决方案似乎只适用于复制作为当前(正在运行的)项目中的资源的文件。

是否可以做这两件事中的一件?

  1. 从外部 clojar 访问资源文件
  2. 将资源文件导入当前项目,以便我可以使用io/resource访问它

最佳答案

正如 dbasch 正确解释的那样,io/resource返回一个 URL,而不是一个文件。但是为什么你能够打开那个 URL io/file在 REPL 或 lein run但不是从 jar 里?那是因为第一种情况下的 URL 指向普通文件在文件系统中,而使用 jar 运行时的 URL 指向 jar 中的资源,因此它不是正确的文件。

我在this github repo做了一个例子.我将复制 -main此处代码供引用:

(defn -main [& args]
(let [r (io/resource "greet")]
(println r)
(println (slurp r))
(with-open [rdr (io/reader r)]
(println (clojure.string/join ", " (line-seq rdr))))
(println (io/file r))))

运行lein run显示:

› lein run
#<URL file:/home/nicolas/projects/clojure/resources/resources/greet>
hello
world

hello, world
#<File /home/nicolas/projects/clojure/resources/resources/greet>

运行 uberjar 显示:

› java -jar target/resources-0.1.0-SNAPSHOT-standalone.jar 
#<URL jar:file:/home/nicolas/projects/clojure/resources/target/resources-0.1.0-SNAPSHOT-standalone.jar!/greet>
hello
world

hello, world
Exception in thread "main" java.lang.IllegalArgumentException: Not a file: jar:file:/home/nicolas/projects/clojure/resources/target/resources-0.1.0-SNAPSHOT-standalone.jar!/greet
at clojure.java.io$fn__8588.invoke(io.clj:63)
at clojure.java.io$fn__8572$G__8556__8577.invoke(io.clj:35)

查看 #<URL file:/home/nico... 之间的区别和 #<URL jar:file:/home/nico... ,这就解释了为什么你不能调用 (io/file)在上面,但你可以用 slurp 阅读它或使用 io/reader 创建阅读器.

关于java - 从外部 clojar 导入/使用资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30857749/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com