将文件读入列表,每个元素代表文件的一行

时间:2012-01-28 17:21:30

标签: file-io clojure

在clojure中,如何将文件读入序列,其中每一行是序列中的一个元素。所以我想看看函数get-lines的定义,所以我可以做到以下几点:

(def lines (get-lines "test.txt"))

和行是一个非惰性序列。

3 个答案:

答案 0 :(得分:10)

替代实施:

(require ['clojure.string :as 'str])

(defn get-lines [file]
  (str/split-lines (slurp file)))

此函数返回结果的向量而不是seq。

如果您不使用1.3,请改为使用clojure.contrib.string。

答案 1 :(得分:8)

要将延迟序列转换为非延迟序列,您可以使用doall,如下所示:

(use 'clojure.java.io)

(defn get-lines [fname]
  (with-open [r (reader fname)]
    (doall (line-seq r))))

答案 2 :(得分:2)

您可以使用line-seq。一个简单的例子:

(ns your.project
  (:require [clojure.java.io :as io]))

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

请注意,line-seqlazy。在关闭阅读器之后,您必须小心不要使用序列。以下内容不起作用:

(def lines (with-open [rdr (io/reader "some-file")]
             (line-seq rdr)))

(println (first lines))

第一个例子有效,因为count不是懒惰的。

如果你想用线条做一些事情(有副作用)你可能会发现doseq最有用:

;; copy every "short" line in file
(with-open [rdr (io/reader from)
            wrt (io/writer to)]
  (binding [*out* wrt]
    (doseq [line (line-seq rdr) :when (< (count line) 10)]
      (println line))))