How to load program resources in Clojure

前端 未结 4 1508
太阳男子
太阳男子 2021-01-31 09:30

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 p

相关标签:
4条回答
  • 2021-01-31 09:51

    I placed the file in testpkg/test.txt (relative to current directory).

    Code:

    (def x 5)
    (def nm "testpkg/test.txt")
    (def thr (Thread/currentThread))
    (def ldr (.getContextClassLoader thr))
    (def strem (.getResourceAsStream ldr nm))
    (def strem2 (ClassLoader/getSystemResource nm))
    (. System/out (println "First Approach:"))
    (. System/out (println strem))
    (. System/out (println))
    (. System/out (println))
    (. System/out (println "Second Approach:"))
    (. System/out (println strem2))
    

    $ java -cp .\;clojure.jar clojure.main test.clj

    First Approach: java.io.BufferedInputStream@1549f94

    Second Approach: file:/C:/jsight/javadevtools/clojure-1.1.0/testpkg/test.txt

    0 讨论(0)
  • 2021-01-31 09:59

    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 to com/domain/scriptingtest/resources in the Java version. In the clojure version, the source file, example.clj is in com/domain. In the Java version, the source file, Example.java is in the com/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.

    0 讨论(0)
  • 2021-01-31 10:00

    you can also use clojure.lang.RT/baseLoader

    (defn serve-public-resource [path]
      (.getResourceAsStream (clojure.lang.RT/baseLoader) (str "public/" path))) 
    
    0 讨论(0)
  • 2021-01-31 10:06
    (clojure.java.io/resource "myscript.js")
    
    0 讨论(0)
提交回复
热议问题