Перенаправить ввод в Clojure

Я хочу перенаправить стандартный ввод в мой тест Clojure. Я передал файл в качестве аргумента и пытаюсь найти эквивалентный код в java: System.setIn (new FileInputStream (filename)); но для Clojure.

Основная проблема заключается в том, что я использую пакет DaCapo для расчета производительности Benchmark, а метод, загружающий тест, не распознает специальные символы, такие как "<", в отличие от cmd (запуск jar теста непосредственно из cmd..).

Это то, что я пытаюсь сделать.. но по-прежнему не работает.. Я думаю, что br имеет стандартный ввод из in, и он используется остальной частью программы. Как я могу изменить вход, когда у меня есть в аргументах желаемый путь, чтобы я мог правильно запустить тест? Это мои усилия с "системой / сеттингом"

(defn -main [& args]
  (let [max-dna-chars-per-line 60
    jk  (with-open [is (clojure.java.io/input-stream (first args))]
        (System/setIn is))
        br (java.io.BufferedReader. *in*)
        bw (java.io.BufferedWriter. *out* (* 16 8192)) ; 16 * default size, I think
        ;; We could use the map complement-dna-char-map instead of
        ;; complement-dna-char-fn, but when I tested that, the program
        ;; spent a lot of time running the hashCode method on
        ;; characters.  I'm hoping this is faster.
        complement-dna-char-vec (make-vec-char-mapper complement-dna-char-map)]
    (loop [[desc-str dna-seq-str more] (fasta-slurp-br br)]
      (println-string-to-buffered-writer bw desc-str)
      (print-reverse-complement-of-str-in-lines bw dna-seq-str
                                                complement-dna-char-vec
                                                max-dna-chars-per-line)
      (when more
        (recur (fasta-slurp-br br))))
    (. bw flush))) 

2 ответа

System.in обычно завернут в *in*, Это динамическое связывание, предназначенное для восстановления в локальной области с binding, вот так:

(with-open [is (clojure.java.io/reader "/tmp/foo.txt")]
  (binding [*in* is]
    (println (read-line))))

Обратите внимание, что это обертка System.inне System.in само по себе, и изменение этой привязки не изменится System.in, Это влияет только на функции Clojure, которые используют *in*, такие как read-line Вот.

Если вы вызываете некоторый код Java, который хочет прочитать System.in, ты должен позвонить System.setIn:

(with-open [is (clojure.java.io/input-stream filename)]
  (System/setIn is)
  (do-stuff))

Это варианты в Clojure и Java, но я все еще не уверен, что понимаю ваш вариант использования. Пожалуйста, уточните в комментариях, если это не совсем имеет смысла.

РЕДАКТИРОВАТЬ: Что касается вашей программы, если вы создаете буферы, вам действительно нужно создать их *in*? В чем разница с открытием собственного потока?

Попробовав так много разных вещей, я наконец нашел ответ...

Мне пришлось использовать средство чтения файлов внутри буфера, поэтому код выглядит так:

(defn -main [& args]
  (let [max-dna-chars-per-line 60
        br (java.io.BufferedReader. (clojure.java.io/reader (first args)))
        bw (java.io.BufferedWriter. *out* (* 16 8192)) ; 16 * default size, I think

где аргументы содержат имя файла...

Другие вопросы по тегам