Search code examples
clojurestdinclojure-java-interop

How to read all lines from stdin in Clojure


I'm writing a Brainf*** interpreter in Clojure. I want to pass a program in using stdin. However, I still need to read from stdin later for user input.

Currently, I'm doing this:

$ cat sample_programs/hello_world.bf | lein trampoline run

My Clojure code is only reading the first line though, using read-line:

(defn -main
  "Read a BF program from stdin and evaluate it."
  []
  ;; FIXME: only reads the first line from stdin
  (eval-program (read-line)))

How can I read all the lines in the file I've piped in? *in* seems to be an instance of java.io.Reader, but that only provides .read (one char), .readLine (one line) and read(char[] cbuf, int off, int len) (seems very low level).


Solution

  • you could get a lazy seq of lines from *in* like this:

    (take-while identity (repeatedly #(.readLine *in*)))
    

    or this:

    (line-seq (java.io.BufferedReader. *in*))
    

    which are functionally identical.