java - 在 Clojure 中捕获系统/输出

标签 java clojure

我正在使用一个将文本输出到控制台的 Java 包,我需要在字符串中捕获该文本,但我不确定如何执行此操作。从 Clojure 文档看来,我所要做的就是将 java 调用包装在 with-out-str 中,但这对我来说不起作用。

最小代码示例:如果我尝试

(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#)
       ~@body
       (finally
         (System/setOut original-out#)))
     (.toString out-buffer# "UTF-8")))

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

关于java - 在 Clojure 中捕获系统/输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37773329/

相关文章:

java - 将 stripe 与 android 应用程序集成

java - Android 在 Activity 中发送电子邮件时给出 "javax.mail.AuthenticationFailedException"

clojure - 在Clojure中,如何对元素进行分组?

clojure - #_ 和 ; 和有什么区别?在 Clojure 中?

java - 将 NekoHTML ElementNSImpl 对象序列化回 HTML/XML

Java ogg 到 wav 转换

java - Java 中克隆列表元素

java - Jersey 测试期间“在调用 getWriter() 后非法尝试调用 getOutputStream()”

java - 在不分配类型的情况下扩展通用接口(interface)?

Emacs 配置