2013-03-05 6 views
6

Clojure 1.5는 PushbackReader을 필요로하는 읽기 기능을 포함하여 clojure.edn을 도입했습니다. 내가 처음 다섯 오브젝트를 읽고 싶다면, 나는clojure.edn/read를 사용하여 파일의 객체 시퀀스를 가져 오는 방법은 무엇입니까?

을 수행 할 수 있습니다

(with-open [infile (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))] 
    (binding [*in* infile] 
    (let [edn-seq (repeatedly clojure.edn/read)] 
     (dorun (take 5 (map println edn-seq)))))) 

어떻게 대신 모든 개체를 인쇄 할 수 있습니까? 그것들 중 일부가 nils 일 수 있다고 생각하면, EOF 나 유사한 것을 검사 할 필요가있는 것 같습니다. line-seq에서 얻을 수있는 것과 유사한 일련의 객체를 갖고 싶습니다. 파일의 마지막에 수익 가치 - EOF :

답변

10

사용 : EOF 키

http://clojure.github.com/clojure/clojure.edn-api.html

OPTS는 다음 키를 포함 할 수 있습니다 맵입니다. 제공되지 않으면, eof는 예외를 던집니다.

편집 : 죄송합니다. 세부 사항이 충분하지 않았습니다. 여기 y'go : 그것은

+1

그래, 설명서에 바로 나와 있습니다. 오케이. 그것은 EOF에 대한 내 자신의 견해를 정의해야하는 다소 더러 웠지만 어쩌면 나는 그게 왜 올바른 해결책인지 아직 몰랐을 것입니다. – ToBeReplaced

+0

@bfontaine 님의 다른 답변보기. 내용 독립성에는 가치가 있지만,': eof' 키에 대해 EDN으로 직렬화 할 수없는 값을 사용하여 얻을 수 있습니다. – ToBeReplaced

3

내가 다시 바라 보았다해야

(with-open [in (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))] 
    (let [edn-seq (repeatedly (partial edn/read {:eof :theend} in))] 
    (dorun (map println (take-while (partial not= :theend) edn-seq))))) 

합니다.

(defn edn-seq 
    "Returns the objects from stream as a lazy sequence." 
    ([] 
    (edn-seq *in*)) 
    ([stream] 
    (edn-seq {} stream)) 
    ([opts stream] 
    (lazy-seq (cons (clojure.edn/read opts stream) (edn-seq opts stream))))) 

(defn swallow-eof 
    "Ignore an EOF exception raised when consuming seq." 
    [seq] 
    (-> (try 
     (cons (first seq) (swallow-eof (rest seq))) 
     (catch java.lang.RuntimeException e 
      (when-not (= (.getMessage e) "EOF while reading") 
      (throw e)))) 
     lazy-seq)) 

(with-open [stream (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))] 
    (dorun (map println (swallow-eof (edn-seq stream))))) 

edn-seqclojure.edn/read과 동일한 서명을 가지고 있으며, 나는 사람들이 다른 방식으로 :eof 옵션을 사용할 수 있다는 주어진 중요하다고 생각 기존의 행동을 모두 보존 : 여기에 내가 무엇을 최대 온 것입니다. 비록 그것이 단지 java.lang.RuntimeException처럼 보여지기 때문에 그것을 포착하는 것이 가장 잘 모르겠지만, EOF 예외를 포함하는 별도의 함수는 더 나은 선택처럼 보였다.

+0

예외의 텍스트를 테스트하는 대신': eof' 인수를 사용하십시오. – bfontaine

+0

오래된 질문/답변,하지만 왜 그렇게 말합니까? ': eof'를 사용하여 구현하면 내용에 독립적이지 않습니다. ': library/eof'도 충돌 할 수 있습니다. 피해야 할 유일한 방법은 사용자가'swallow-eof'의 일부로 스스로 : eof 값을 전달하도록하는 것입니다. – ToBeReplaced

+0

EDN은 Clojure 값의 하위 집합이므로 함수처럼 EDN으로 직렬화 할 수없는 Clojure 값을 제공하면됩니다. – bfontaine