"lein run" 和 运行 uberjar 文件的不同 slurp 行为

Different slurp behavior with "lein run" and running the uberjar file

我目前正在尝试学习 Clojure,作为我实践培训的一部分,我正在 实现一些众所周知的 Unix 工具的基本行为,例如 grepcatls 等等。

在实施 cat 时,我偶然发现了一些看似奇怪的行为 slurp。当我 运行 以下代码与 lein run some-file.txtsome-file.txt 位于当前目录中,内容按预期打印到 STDOUT。

(ns cat.core
  (:gen-class))

(defn -main
  "Reads the content of its arguments representing filenames and outputs the
  content in succession."
  [& filenames]
  (doseq [filename filenames]
    (println "Reading" filename) ; Just for debugging purposes
    (print (slurp filename))))

但是,如果我 uberjar 项目

lein compile
lein uberjar

然后 cdtarget/uberjar 到 运行 独立的 JAR java -jar cat-0.1.0-SNAPSHOT-standalone.jar some-file.txt(文本文件存在于该目录中), 除了我的调试消息外,什么都没有打印。我觉得很奇怪的是没有错误 正在显示消息,所以在我看来可以找到该文件。如果我 运行 带有不存在的文件作为参数的 JAR,我得到一个指定的异常 找不到文件(如预期的那样)。

因为我在 Windows 机器上工作,同事建议也许 Windows 影子文件可能是个问题。所以我再次测试了 Linux 下的程序,并且 发生了同样的行为。所以这似乎是 "problem" 我对 Clojure 的理解/我的项目 设置。

我的问题是:为什么 slurp(或程序)在 运行 lein run 和 运行 将独立 JAR 与 java -jar cat-0.1.0-SNAPSHOT-standalone.jar 我该怎么做才能解决这个问题?

由于文件参数不是编译到JAR中的资源,所以没有 如果我没记错的话需要 (slurp (clojure.java.io/resource filename))

print 不刷新输出缓冲区。您需要在 print 语句之后使用 flush,或者使用另一个 println,它会刷新换行符:

(defn -main
  "Reads the content of its arguments representing filenames and outputs the
  content in succession."
  [& filenames]
  (doseq [filename filenames]
    (print (slurp filename))
    (flush)))