4

Clojureで処理したい大きなテキストファイルがあります。
一度に2行処理する必要があります。

次のバインディングを使用して、パスごとに2行をプルできるように、forループを使用することにしました(rdrは私のリーダーです)。

[[line-a line-b] (partition 2 (line-seq rdr))]

(ループの反復ごとに2行を取得する他の方法を知りたいと思いますが、それは私の質問のポイントではありません)。

ループを機能させようとすると(これらのテストに単純なバインディングを使用して)、説明できない次の動作が見られます。

どして

(with-open [rdr (reader "path/to/file")]  
    (for [line (line-seq rdr)]  
          line))  

ストリームクローズ例外をトリガーする

その間

(with-open [rdr (reader "path/to/file")]  
    (doseq [line (line-seq rdr)]  
        (println line)))

動作しますか?

4

1 に答える 1

7

forは怠惰であり、最終的にファイルからデータを読み取るシーケンスの先頭を返すだけです。forの内容が担当者によって印刷されるとき、ファイルはすでに閉じられています。あなたはこのpuラッピングを修正することができforますdoall

(with-open [rdr (reader "path/to/file")]  
    (doall (for [line (line-seq rdr)]  
      line)))  

これはシーケンスを怠惰にしますが。

これが私のmisc.cljからの関数のサンプルで、ファイルの最後で怠惰に閉じます。

(defn byte-seq [rdr]
  "create a lazy seq of bytes in a file and close the file at the end"
  (let [result (. rdr read)]
    (if (= result -1)
     (do (. rdr close) nil)
     (lazy-seq (cons result (byte-seq rdr))))))
于 2012-08-17T00:19:24.493 に答える