5

给定一个输入流,我想以字节数组(块)的形式创建一个惰性数据序列。这是我的尝试:

(defn- read-or-nil [stream]
  (let [buf (byte-array 2)]
    (when-not (= -1 (.read stream buf))
      buf)))

(defn byte-chunk-seq [stream]
  (cons (read-or-nil stream) (lazy-seq (byte-chunk-seq stream))))

(with-open [rdr (java.io.FileInputStream. "/tmp/wut")]                                                                                                                                                                                         
  (take 2 (byte-chunk-seq rdr))) 

在最后一个语句中,我正在测试代码,我得到:

IOException 流已关闭 java.io.FileInputStream.readBytes (FileInputStream.java:-2)

如果我将语句更改为 atake 1那么它返回正常,但这对我没有多大帮助。有谁知道为什么这不起作用?

4

1 回答 1

4

有几个问题。

首先,您的惰性序列并不完全正确。整个函数体应该用 包裹起来lazy-seq,它应该传入 cons 来继续序列,或者传入 nil 来终止它。

(defn byte-chunk-seq [stream]
  (lazy-seq (if-let [buf (read-or-nil stream)]
              (cons buf (byte-chunk-seq stream))
              nil)))

take是也懒。with-open因此,只有在关闭流之后才能实现惰性序列。doall您可以通过在惰性序列周围包裹 a 以在流关闭之前实现它来避免此错误。

(with-open [rdr (java.io.FileInputStream. "/tmp/wut")]
  (doall (take 2 (byte-chunk-seq rdr))))
于 2013-06-29T03:37:05.713 回答