问题描述
如何在Clojure程序中加载程序资源,如图标,字符串,图形元素,脚本等?我使用的项目布局类似于许多Java项目,其中有一个资源目录挂在源目录。一个jar文件是从源代码创建的,并且包含了资源,但我似乎无法像Java一样获得加载的资源。
我试过的第一件事是类似
(ClassLoader / getSystemResourceresources / myscript.js)
但是却找不到资源。
...
(let [cls(.getClass net.mydomain.somenamespace)
strm(.getResourceAsStream cls name )]
...
其中name是
/ code>要加载的资源,但流是
nil
。
上下文类加载器与
...
(let [thr(Thread / currentThread )
ldr(.getContextClassLoader thr)
strem(.getResourceAsStream ldr name)]
...
但
strem
始终为零。
将资源文件放置在程序中的每个目录中。
我已经查看了
的语言来源,加载
函数和运行时库,但不是获取。
任何帮助将不胜感激。 b
$ bEDIT :这是一个更具体的例子。在Java中,如果你想将MarkDown转换为HTML,你可以使用
showdown.js
脚本,并写如下:package scriptingtest;
import java.io.InputStreamReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class示例{
private Object converter;
public String transformMarkDown(String markdownString){
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName(js);
try {
engine.eval(new InputStreamReader(getClass()。getResourceAsStream(
resources / showdown.js)));
converter = engine.eval(new Showdown.converter());
} catch(Exception e){
return无法创建转换器;
}
try {
return((Invocable)engine).invokeMethod(converter,makeHtml,
markdownString).toString
} catch(Exception e){
return转换失败;
}
}
public static void main(String [] args){
System.out.println(new Example()。transformMarkDown强调*,**强**));
}
}
当我创建项目时,包装入罐。运行时,程序输出
< p> plain,< em> emphasis< / em>,< strong> strong< / strong>< / p>
/ p>
对Clojure的直译可能非常简单,但是我试图创建
InputStreamReader
编辑:自从帖子后添加了markdown标签
解决方案这是目录结构。
继续使用OP中的脚本引擎示例,Clojure等效项将是:
(ns com.domain。示例
(:gen-class)
(:import(java.io InputStreamReader))
(:import(javax.script ScriptEngineManager ScriptEngine)))
defn load-resource
[name]
(let [rsc-name(strcom / domain / resources /name)
thr(Thread / currentThread)
ldr getContextClassLoader thr)]
(.getResourceAsStream ldr rsc-name)))
(defn markdown-to-html
[mkdn]
ScriptEngineManager)
引擎(.getEngineByName managerjs)
是(InputStreamReader。 (load-resourceshowdown.js))
_(.eval engine is)
cnv-arg(strnew Showdown.converter()。makeHtml(\mkdn\ ))]
(.eval engine cnv-arg)))
(defn -main
[]
(println(markdown-to-htmlplain ,* emphasis *,** strong **)))
注意,资源的路径在Java版本中与
com / domain / scriptingtest / resources
相反,com / domain / resources
在clojure版本中,源文件example.clj
位于com / domain
中。在Java版本中,源文件Example.java
位于com / domain / scriptingtest
包中。 p>
在我的IDE(NetBeans)中设置项目时,Java项目向导会要求提供源代码的封装包。 Clojure插件,enclojure,要求一个命名空间,而不是一个包。我从来没有注意到差别。因此,目录结构中的off-by-one错误预期。
How do you load program resources such as icons, strings, graphical elements, scripts, and so on in a Clojure program? I am using a project layout similar to that in many Java projects where there is a "resources" directory hanging off of a "source" directory. A jar file is created from the source and includes the resources, but I can't seem to get the resources loaded as I would in Java.
The first thing I tried was something like
(ClassLoader/getSystemResource "resources/myscript.js")
But could never find the resource.
You can do something similar with
... (let [cls (.getClass net.mydomain.somenamespace) strm (.getResourceAsStream cls name) ] ...
where name is the
name
of the resource to load, but the stream isnil
.You can try using the context class loader with something like
... (let [thr (Thread/currentThread) ldr (.getContextClassLoader thr) strem (.getResourceAsStream ldr name)] ...
But
strem
is always nil.In frustration, I've tried placing the resource files in just about every directory in the program. They get copied into the jar correctly, but I still can't seem to load them.
I've looked at the language sources for the
load
function and the run-time library, but am not "getting" it.Any help would be appreciated.
EDIT: Here's a more concrete example. In Java, if you wanted to convert MarkDown to HTML, you might use the
showdown.js
script and write something like:package scriptingtest; import java.io.InputStreamReader; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Example { private Object converter; public String transformMarkDown(String markdownString) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); try { engine.eval(new InputStreamReader(getClass().getResourceAsStream( "resources/showdown.js"))); converter = engine.eval("new Showdown.converter()"); } catch (Exception e) { return "Failed to create converter"; } try { return ((Invocable) engine).invokeMethod(converter, "makeHtml", markdownString).toString(); } catch (Exception e) { return "Conversion failed"; } } public static void main(String[] args) { System.out.println(new Example().transformMarkDown("plain, *emphasis*, **strong**")); } }
when I create the project, it all gets compiled and packed into a jar. When run, the program outputs
<p>plain, <em>emphasis</em>, <strong>strong</strong></p>
A literal translation to Clojure seems pretty straightforward, but I run into trouble trying to create the
InputStreamReader
-- I can't seem to write the code needed to find the script file in the jar.Edit: Added "markdown" tag since the post gives two complete examples of approaches to processing markdown.
解决方案It's the directory structure.
Continuing with the scripting engine example in the OP, a Clojure equivalent would be:
(ns com.domain.example (:gen-class) (:import (java.io InputStreamReader)) (:import (javax.script ScriptEngineManager ScriptEngine))) (defn load-resource [name] (let [rsc-name (str "com/domain/resources/" name) thr (Thread/currentThread) ldr (.getContextClassLoader thr)] (.getResourceAsStream ldr rsc-name))) (defn markdown-to-html [mkdn] (let [manager (new ScriptEngineManager) engine (.getEngineByName manager "js") is (InputStreamReader. (load-resource "showdown.js")) _ (.eval engine is) cnv-arg (str "new Showdown.converter().makeHtml(\"" mkdn "\")")] (.eval engine cnv-arg))) (defn -main [] (println (markdown-to-html "plain, *emphasis*, **strong**")))
Note that the path to the resources is
com/domain/resources
for this code as opposed tocom/domain/scriptingtest/resources
in the Java version. In the clojure version, the source file,example.clj
is incom/domain
. In the Java version, the source file,Example.java
is in thecom/domain/scriptingtest
package.When setting up a project in my IDE, NetBeans, the Java project wizard asks for an enclosing package for the source. The Clojure plugin, enclojure, asks for a namespace, not a package. I had never noted that difference before. Hence the "off-by-one" error in the directory structure expected.
这篇关于如何在Clojure中加载程序资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!