2013-06-29 11 views
5

入力ストリームがある場合、バイト配列(チャンク)の形式でデータのレイジーシーケンスを作成したいと考えています。ここに私の試みだ:Clojure:入力ストリームからバイトチャンクのレイジーシーケンスを作成する

にIOExceptionストリームを閉じたjava.io.FileInputStream.readBytes(FileInputStream.java:-2:私は、コードをテストしています最後の文では、

(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))) 

、私が取得します)

ステートメントをtake 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))) 

第2に、takeも怠惰です。したがって、遅いシーケンスは、with-openがストリームを終了するまで実現されません。ストリームが閉じられる前に、レイジーシーケンスの周りにdoallをラップすることによって、このエラーを回避できます。

(with-open [rdr (java.io.FileInputStream. "/tmp/wut")] 
    (doall (take 2 (byte-chunk-seq rdr)))) 
関連する問題