java Capturing System/out in Clojure

i86rm4rw  于 2023-06-28  发布在  Java
关注(0)|答案(3)|浏览(102)

我正在使用一个将文本输出到控制台的Java包,我需要将该文本捕获到字符串中,但我不确定如何做到这一点。从Clojure文档来看,似乎我所要做的就是将java调用 Package 在with-out-str中,但这对我来说不起作用。
最小代码示例:如果我尝试

(with-out-str 
 (.println (System/out) "foo"))

我希望得到一个值为“foo”的字符串,但它仍然输出到控制台。我做错了什么?

u0sqgete

u0sqgete1#

Java的System.out.println(...)是对PrintStream示例的println方法的调用。您需要用自己的示例替换System.out流并捕获其内容:

(import [java.io ByteArrayOutputStream PrintStream])

(def out-buffer (java.io.ByteArrayOutputStream.))

(System/setOut (java.io.PrintStream. out-buffer true "UTF-8"))

(defn out-str []
  (.toString out-buffer "UTF-8"))

但是在REPL中要小心,因为它使用System.out来打印结果,所以当你全局替换它时,它会破坏你的REPL示例。
您甚至可以编写一个宏来捕获System.out的内容,然后恢复原始的PrintStream示例:

(defmacro with-system-out-str [& body]
  `(let [out-buffer# (ByteArrayOutputStream.)
         original-out# System/out
         tmp-out# (PrintStream. out-buffer# true "UTF-8")]
     (try
       (System/setOut tmp-out#)
       ~@body
       (finally
         (System/setOut original-out#)))
     (.toString out-buffer# "UTF-8")))

(with-system-out-str
  (.println System/out "Hi"))
;; => "Hi\n"
nhjlsmyf

nhjlsmyf2#

您可以将输出保存到文件中,然后读取文件的内容。

(def foo-file (clojure.java.io/writer "foo.txt"))

(binding [*out* foo-file]
  (println "Foo, bar."))

(println "Slurp: " (slurp "foo.txt"))
nmpmafwu

nmpmafwu3#

Tupelo库包括with-system-out-str和with-system-err-str

相关问题