如何在Clojure中以非阻塞方式读取非空标准输入(*in*
)?
首先,我认为使用java.io.Reader#ready()
方法进行调用会有效,但即使提供标准输入,(.ready *in*)
也会返回false
。
答案 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吗?您可以像使用它一样使用它:
https://docs.oracle.com/javase/8/docs/api/index.html?java/io/PushbackReader.html
如果您需要将其设置为非阻止,请将其粘贴到future
,core.async
频道或类似频道。