在Clojure中检测非空STDIN

时间:2017-01-10 18:03:35

标签: clojure stdin

如何在Clojure中以非阻塞方式读取非空标准输入(*in*)?

首先,我认为使用java.io.Reader#ready()方法进行调用会有效,但即使提供标准输入,(.ready *in*)也会返回false

2 个答案:

答案 0 :(得分:2)

这是你在找什么? InputStream .available

(defn -main [& args]
  (if (> (.available System/in) 0)
    (println "STDIN: " (slurp *in*))
    (println "No Input")))
$ echo "hello" | lein run
STDIN:  hello

$ lein run
No Input

更新.available似乎是检查STDIN的竞争条件。另一种方法是让STDIN有一个固定的超时可用,否则假设没有数据来自STDIN

以下是使用core.async尝试从STDIN读取第一个字节并将其附加到STDIN的其余部分或超时的示例。

(ns stdin.core
  (:require
   [clojure.core.async :as async :refer [go >! timeout chan alt!!]])
  (:gen-class))

(defn -main [& args]
  (let [c (chan)]
    (go (>! c (.read *in*)))
    (if-let [ch (alt!! (timeout 500) nil
                       c ([ch] (if-not (< ch 0) ch)))]
      (do
        (.unread *in* ch)
        (println (slurp *in*)))

      (println "No STDIN")))) 

答案 1 :(得分:0)

你看过PushbackReader吗?您可以像使用它一样使用它:

  1. 读取一个字节(阻塞)。如果流被关闭,则返回char read或-1。
  2. 返回时,您知道一个字节已准备就绪。
  3. 如果该字节是您尚未准备好的,请将其放回去
  4. 如果流关闭(-1返回val),则退出。
  5. 重复。
  6. https://docs.oracle.com/javase/8/docs/api/index.html?java/io/PushbackReader.html

    如果您需要将其设置为非阻止,请将其粘贴到futurecore.async频道或类似频道。