I’m working with a Java package that outputs text to the console and I need to capture that text in a string, but I’m not sure how to do this. From looking at the Clojure documentation it seemed that all I have to do is wrap the java call in with-out-str
but that isn’t working for me.
Minimal code example: if I try
(with-out-str (.println (System/out) "foo"))
I’m hoping to get a string with the value “foo”, but it’s still outputting to the console instead. What am I doing wrong?
Answer
Java’s System.out.println(...)
is a call to println
method of PrintStream
instance. You need to replace the System.out
stream with your own instance and capture its content:
(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"))
Watch out in the REPL though because it uses System.out
to print the results so when you replace it globally, it will break your REPL instance.
You can even write a macro that will capture the content of the System.out
and then restore the original PrintStream
instance:
(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")) ;; => "Hin"