【发布时间】:2015-06-16 02:11:05
【问题描述】:
我想要做的是在独立的 Maven 存储库/clojar 中打包一个大文件(MIDI 声音字体),然后能够以编程方式将其拉下并从单独的项目中使用它。事实证明,这个看似简单的任务比我预期的要复杂。
如果有一种方法可以直接访问这些资源,或者将它们公开为公共变量或其他方式,那么理想的情况是。这是我尝试的第一件事——我做了这样的事情:
(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上被问过的类似问题,比如:
- Idiomatic Clojure to copy resources from running jar to outside
- How to copy file inside jar to outside the jar?
然而,这些解决方案似乎只适用于复制作为 当前(正在运行的)项目中的资源的文件。
是否可以做这两件事之一?
- 从外部 clojar 访问资源文件
- 将资源文件导入到当前项目中,以便我可以使用
io/resource访问它
【问题讨论】:
-
将资源复制到文件中就是您的答案。正如错误消息所述,jar 内的资源不是文件。这不是类路径问题,这是一个基本事实,即 jar 中的资源不是文件。
-
“不是文件”似乎是 Java 告诉我它不能用不存在的资源制作文件的方式。运行
(io/file (io/resource "fluid-r3.sf2"))在midi.soundfont.fluid-r3项目(其资源目录包含该文件)的类路径上运行时有效,但在任何其他项目中运行时会引发“不是文件”异常。 -
澄清一下,我可以将资源复制到文件中。问题是从另一个项目中执行此操作。这有意义吗?
-
这不是从资源中创建文件的方式。
io/file的参数必须是可以用作文件的东西——jar 内的资源条目根本不符合条件。您可以从资源中读取并写入实际文件,如您帖子中的链接中所述。 -
根据定义,资源是类路径上的东西。你可以啜饮资源。您可以从资源复制到字节数组或输出流或实际文件中。但是您不能简单地将资源强制为文件,除非您的 URI 指向磁盘上的某个位置。