我正在使用一個Java包輸出文本到控制檯,我需要捕獲一個字符串中的文本,但我不知道如何做到這一點。從查看Clojure文檔看來,我所要做的就是將這個java調用封裝在with-out-str
中,但這對我不起作用。在Clojure捕獲系統/出
最少的代碼示例:如果我嘗試
(with-out-str
(.println (System/out) "foo"))
我希望能獲得與「foo」值的字符串,但它仍然輸出到控制檯。我究竟做錯了什麼?
我正在使用一個Java包輸出文本到控制檯,我需要捕獲一個字符串中的文本,但我不知道如何做到這一點。從查看Clojure文檔看來,我所要做的就是將這個java調用封裝在with-out-str
中,但這對我不起作用。在Clojure捕獲系統/出
最少的代碼示例:如果我嘗試
(with-out-str
(.println (System/out) "foo"))
我希望能獲得與「foo」值的字符串,但它仍然輸出到控制檯。我究竟做錯了什麼?
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#)
[email protected]
(finally
(System/setOut original-out#)))
(.toString out-buffer# "UTF-8")))
(with-system-out-str
(.println System/out "Hi"))
;; => "Hi\n"
您可以將輸出保存到文件中,然後讀取文件的內容。
(def foo-file (clojure.java.io/writer "foo.txt"))
(binding [*out* foo-file]
(println "Foo, bar."))
(println "Slurp: " (slurp "foo.txt"))