2013-03-05 4 views
6

क्लोजर 1.5 ने clojure.edn पेश किया, जिसमें एक पढ़ा गया फ़ंक्शन शामिल है जिसके लिए PushbackReader की आवश्यकता होती है।किसी फ़ाइल में ऑब्जेक्ट्स का अनुक्रम प्राप्त करने के लिए clojure.edn/पढ़ने के लिए कैसे उपयोग करें?

मैं पहले पांच वस्तुओं को पढ़ने के लिए चाहते हैं, तो मैं कर सकते हैं:

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

मैं कैसे बजाय वस्तुओं की सभी प्रिंट कर सकते हैं? यह मानते हुए कि उनमें से कुछ नील हो सकते हैं, ऐसा लगता है कि मुझे ईओएफ, या कुछ इसी तरह की जांच करने की आवश्यकता है। मैं line-seq से प्राप्त होने वाली वस्तुओं के अनुक्रमों के समान होना चाहता हूं।

उत्तर

10

उपयोग:: - मूल्य अंत के फ़ाइल पर वापसी के लिए EOF: EOF कुंजी

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

opts एक नक्शा है जो निम्न कुंजी शामिल कर सकते हैं। जब आपूर्ति नहीं की जाती है, तो एक अपवाद फेंकता है।

संपादित करें: क्षमा करें, यह पर्याप्त जानकारी नहीं थी! यहाँ y'go:

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

कि यह

+1

हाँ, यह दस्तावेज़ में ठीक था। ओह। यह ईओएफ के लिए अपने स्वयं के सेंटीनेल को परिभाषित करने के लिए थोड़े गंदे लगता है, लेकिन हो सकता है कि मैंने अभी तक गड़बड़ नहीं की है कि यह अभी तक सही समाधान क्यों है। – ToBeReplaced

+0

अन्य उत्तर पर @bfontaine द्वारा टिप्पणियां देखें। सामग्री-स्वतंत्रता रखने में मूल्य है, लेकिन आप इसे 'eof' कुंजी के लिए किसी भी मान का उपयोग करके प्राप्त कर सकते हैं जो ईडीएन के रूप में क्रमिक नहीं है। – ToBeReplaced

3

मैं फिर से इस पर ध्यान करना चाहिए।

(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 के रूप में दिखाई देता है।

+0

अपवाद के पाठ पर परीक्षण के बजाय ': eof' तर्क का उपयोग करें। – bfontaine

+0

पुराना प्रश्न/उत्तर, लेकिन आप ऐसा क्यों कहते हैं? यदि आप ': eof' के साथ कार्यान्वित करते हैं, तो आप सामग्री-स्वतंत्र नहीं हैं। यहां तक ​​कि 'लाइब्रेरी/ईओएफ' टकरा सकता है। बचने का एकमात्र तरीका यह होगा कि उपयोगकर्ता को 'निगल-ईओएफ' के हिस्से के रूप में खुद को पास करने के लिए मजबूर होना होगा। – ToBeReplaced

+0

ईडीएन क्लोजर मूल्यों का एक सबसेट है, इसलिए आपको केवल एक क्लोजर वैल्यू देना है जो एक फ़ंक्शन की तरह ईडीएन के रूप में क्रमबद्ध नहीं है। – bfontaine

संबंधित मुद्दे

 संबंधित मुद्दे