我使用的Java包将文本输出到控制台,我需要在字符串中捕获该文本,但我不知道如何做到这一点。从查看Clojure文档看来,我所要做的就是将with-out-str
中的java调用包装起来,但这对我来说并不适用。
最小代码示例:如果我尝试
(with-out-str
(.println (System/out) "foo"))
我希望得到一个值为#34; foo"的字符串,但它仍然会输出到控制台。我做错了什么?
答案 0 :(得分:6)
Java System.out.println(...)
是对println
实例的PrintStream
方法的调用。您需要将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"
答案 1 :(得分:0)
您可以将输出保存到文件中,然后读取文件的内容。
(def foo-file (clojure.java.io/writer "foo.txt"))
(binding [*out* foo-file]
(println "Foo, bar."))
(println "Slurp: " (slurp "foo.txt"))