Logging 如何使用core.async在Clojure中写入日志文件?

Logging 如何使用core.async在Clojure中写入日志文件?,logging,asynchronous,clojure,java-io,core.async,Logging,Asynchronous,Clojure,Java Io,Core.async,我想将core.async用作写入文件的记录器,因此我创建了一个test.txt文件,将其放在我的resources文件夹中,并编写了以下代码: (use 'clojure.java.io) (use 'clojure.core.async) (def print-chan (chan)) (go (loop [] (when-let [v (<! print-chan)] (with-open [wrtr (writer "resources/test.t

我想将core.async用作写入文件的记录器,因此我创建了一个test.txt文件,将其放在我的resources文件夹中,并编写了以下代码:

(use 'clojure.java.io)
(use 'clojure.core.async)

(def print-chan (chan))

(go (loop []
      (when-let [v (<! print-chan)]
        (with-open [wrtr (writer "resources/test.txt" :append true)]
          (.write wrtr v))
        (recur)))) 

(>!! print-chan 42)
(使用“clojure.java.io”)
(使用“clojure.core.async”)
(陈德福)
(go(loop[]
(当让[v](打印chan 42)
然而,当我运行这个程序时,我发现它只会替换文件中的内容,而不会附加到文件中。此外,有时写入文件的输出是奇怪的。有一次,我尝试输入42,结果得到了*。当我使用writer而不使用core.async函数时,它会按预期工作。在Clojur中写入日志文件的惯用方法是什么e使用core.async?提前感谢

*我用的是光桌。

wrtr
是一个

当您将
42
(long)发送到通道中时,您正在调用调用此方法的
(.write wrtr 42)

write(int c)
Writes a single character.
42
表示上的
\*
字符,因此这就是正在编写的内容

相反,您希望通过
(.write wrtr“42”)
调用此Writer方法:

您可以通过将从通道读取的值转换为字符串来实现这一点:

(.write wrtr (str v))

在每个循环/重现周期中,您都会重新打开文件,这就是它不追加的原因

您需要做的是在程序的生命周期中打开编写器一次

(go
  (with-open [wrtr (writer "resources/test.txt" :append true)]
    (loop []
      (when-let [v (<! print-chan)]
        (.write wrtr (str v "\n"))
      (recur)))) 
(开始
(打开[wrtr(writer“resources/test.txt”:append true)]
(循环[]
(何时出租(

我今天不得不写这样的代码。我发现你必须在goroutine中用open调用
,您不能将
with open
宏与
go loop
宏一起使用。

感谢您提供了这个超级简单且有用的答案。我现在唯一的问题是让它将每个项目打印到一个新行。我是否应该查看Clojure或Java文档来解决这个问题?只需在日志行之后写一个
换行即可。或者把它写在消息中:
(.write wrtr“42\n”)
,或者明确地写:
(.write wrtr“\n”)
。完全正确。只需将行更改为
(.write wrtr(str v“\n”)
(go
  (with-open [wrtr (writer "resources/test.txt" :append true)]
    (loop []
      (when-let [v (<! print-chan)]
        (.write wrtr (str v "\n"))
      (recur))))