Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader.
;; Count lines of a file (loses head): user=> (with-open [rdr (clojure.java.io/reader "/etc/passwd")] (count (line-seq rdr)))
(import '(java.io BufferedReader StringReader)) ;; line terminators are stripped user=> (line-seq (BufferedReader. (StringReader. "1\n2\n\n3"))) ("1" "2" "" "3") ;; empty string gives nil user=> (line-seq (BufferedReader. (StringReader. ""))) nil
;; read from standard input user=> (nth (line-seq (java.io.BufferedReader. *in*)) 2) #_=> 0 #_=> 1 #_=> 2 "2"
;; read a list of lines from a file in the resource directory ;; suppose the resource file xyzzy/names.csv has lines of the following form, ;; and we'd like to collect all the male names from year 1966 ;; ;; gender;name;year;occurrences ;; F;mary;1965;12 ;; M;john;1966;56 ;; F;sally;1971;5 ;; (let [s (clojure.java.io/resource "xyzzy/names.csv")] (with-open [r (clojure.java.io/reader s)] (into #{} (for [line (rest (line-seq r)) :let [[gender name year _] (clojure.string/split line #";")] :when (and (= "1966" year) (= "M" gender))] name))))
Reads the next line from stream that is the current value of *in* .
Documentation says that line-seq
returns a lazy sequence, however
the actual return value is a Cons
cell of the first line to a LazySeq
of
the second line. Calling realized?
on the Cons
cell will fail with an exception.
(cons (.readLine rdr) (lazy-seq (line-seq rdr)))
Example:
(def rdr (BufferedReader. (StringReader. " 1\n 2\n 3")))
(def x (line-seq rdr))
(class x)
=> clojure.lang.Cons
(realized? x)
=> Execution error (ClassCastException) class clojure.lang.Cons cannot be cast to class clojure.lang.IPending
The first line was eagerly realized by the initial call to the line-seq
.
(.readLine rdr)
=> " 2"