【问题标题】:How do you write to a log file in Clojure, using core.async?如何使用 core.async 在 Clojure 中写入日志文件?
【发布时间】:2014-06-29 07:19:42
【问题描述】:

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

(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)

但是,当我运行它时,我发现它只会替换文件中的内容,而不是附加到文件中。此外,有时写入文件的输出是奇怪的。有一次,我尝试输入 42,结果却得到了 *。当我使用没有 core.async 功能的编写器时,它按预期工作。使用 core.async 在 Clojure 中写入日志文件的惯用方式是什么?提前致谢!

*我正在使用灯台。

【问题讨论】:

    标签: logging asynchronous clojure java-io core.async


    【解决方案1】:

    wrtrjava.io.BufferedWriter

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

    write(int c)
    Writes a single character.
    

    42 代表ASCII table 上的\* 字符,所以这就是正在写入的内容。

    相反,您想通过 (.write wrtr "42") 调用此 Writer 方法:

    write(String str)
    Writes a string.
    

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

    (.write wrtr (str v))
    

    【讨论】:

    • 感谢这个超级简单和有用的答案。我现在唯一的问题是让它将每个项目打印到一个新行。我应该查看 Clojure 或 Java 文档来解决这个问题吗?
    • 在你的日志行后面写一个newline。要么将其包含在消息中:(.write wrtr "42\n"),要么明确写入:(.write wrtr "\n")
    • 没错。只需将行更改为(.write wrtr (str v "\n"))
    【解决方案2】:

    您在每个循环/重复循环中重新打开文件,这就是它不附加的原因。

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

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

    我今天只需要编写这样的代码。我发现你必须在 goroutine 中调用with-open。因此(我假设),您不能将 with-open 宏与 go-loop 宏一起使用。

    【讨论】:

      猜你喜欢
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-02
      • 2013-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多