Подтвердить что ты не робот

Как загрузить ресурсы программы в Clojure

Как вы загружаете программные ресурсы, такие как значки, строки, графические элементы, скрипты и т.д. в программе Clojure? Я использую макет проекта, аналогичный такому во многих проектах Java, где есть каталог ресурсов, зависающий от "исходного" каталога. Файл jar создается из источника и включает в себя ресурсы, но я не могу получить загруженные ресурсы, как я был бы в Java.

Первое, что я пробовал, было что-то вроде

(ClassLoader/getSystemResource "resources/myscript.js")

Но никогда не мог найти ресурс.

Вы можете сделать что-то подобное с

...
  (let [cls (.getClass net.mydomain.somenamespace)
        strm (.getResourceAsStream cls name)        ]
...

где name является name ресурса для загрузки, но поток nil.

Вы можете попробовать использовать загрузчик класса контекста с чем-то вроде

...

(let [thr (Thread/currentThread)
      ldr (.getContextClassLoader thr)
      strem (.getResourceAsStream ldr name)]
...

Но strem всегда равно nil.

В отчаянии я попытался разместить файлы ресурсов практически в каждом каталоге программы. Они правильно копируются в банку, но я все еще не могу их загрузить.

Я просмотрел источники языка для функции load и библиотеки времени выполнения, но я не "получаю" ее.

Любая помощь будет оценена.

EDIT. Здесь приведен более конкретный пример. В Java, если вы хотите преобразовать MarkDown в HTML, вы можете использовать showdown.js script и написать что-то вроде:

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**"));
    }
}

когда я создаю проект, он все компилируется и упаковывается в банку. При запуске программа выводит <p>plain, <em>emphasis</em>, <strong>strong</strong></p>

Дословный перевод на Clojure кажется довольно простым, но я столкнулся с трудностями при создании InputStreamReader - я не могу написать код, необходимый для поиска файла script в банке.

Изменить: добавлен тег "markdown", поскольку сообщение дает два полных примера подходов к обработке уценки.

4b9b3361

Ответ 1

Это структура каталогов.

Продолжая пример сценария сценария в OP, эквивалент Clojure:

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

Обратите внимание, что путь к ресурсам com/domain/resources для этого кода, а не com/domain/scriptingtest/resources в версии Java. В версии Clojure исходный файл example.clj находится в com/domain. В версии Java исходный файл Example.java находится в пакете com/domain/scriptingtest.

При настройке проекта в моей среде IDE, NetBeans, мастер проекта Java запрашивает закрытый пакет для источника. Плагин Clojure, enclojure, запрашивает пространство имен, а не пакет. Раньше я никогда не замечал этой разницы. Следовательно, ожидаемая ошибка "по-одному" в структуре каталогов.

Ответ 2

(clojure.java.io/resource "myscript.js")

Ответ 3

вы также можете использовать clojure.lang.RT/baseLoader

(defn serve-public-resource [path]
  (.getResourceAsStream (clojure.lang.RT/baseLoader) (str "public/" path))) 

Ответ 4

Я поместил файл в testpkg/test.txt(относительно текущего каталога).

код:

(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

Первый подход: [email protected]

Второй подход: Файл:/C:/jsight/javadevtools/ clojure -1.1.0/testpkg/test.txt