Xiufen Xu
Xiufen Xu

Reputation: 531

How to read n lines from a file in clojure

I want to read first n lines from a file using clojure. Here is my code:

(defn read-nth-line [file]
  (with-open [rdr (reader file)]
    (loop [line-number 0]
      (when (< line-number 20)
            (nth (line-seq rdr) line-number)
            (recur (inc line-number))))))

but when I run

 user=> (read-nth-line "test.txt")

 IndexOutOfBoundsException   clojure.lang.RT.nthFrom (RT.java:871)

I have no idea why I got such an error.

Upvotes: 10

Views: 2613

Answers (1)

Sam Estep
Sam Estep

Reputation: 13294

Your code produces an out-of-bounds error because you call line-seq multiple times on the same reader. If you want to get a number of lines from a reader, you should call line-seq only once, then take the desired number of lines from that sequence:

(require '[clojure.java.io :as io])

(defn lines [n filename]
  (with-open [rdr (io/reader filename)]
    (doall (take n (line-seq rdr)))))

Example:

(run! println (lines 20 "test.txt"))

If test.txt contains fewer than 20 lines, this will simply print all the lines in the file.

Upvotes: 20

Related Questions