2016-09-02 7 views
8

में एक अंगूठी एप्लिकेशन में कोई ज़िप फ़ाइल स्ट्रीम मैं एक अंगूठी हैंडलर कि करने की जरूरत है:उत्पन्न और Clojure

  • पिन कुछ फ़ाइलों
  • स्ट्रीम ग्राहक के लिए पिन।

अब मेरे पास यह काम कर रहा है, लेकिन केवल पहली ज़िप प्रविष्टि स्ट्रीम हो जाती है, और इसके बाद यह स्टाल/स्टॉप हो जाती है। मुझे लगता है कि यह गलत है फ्लशिंग/स्ट्रीमिंग के साथ कुछ करने के लिए है।

यहाँ मेरी (compojure) हैंडलर है:

(GET "/zip" {:as request} 
      :query-params [order-id :- s/Any] 
      (stream-lessons-zip (read-string order-id) (:db request) (:auth-user request))) 

यहाँ धारा-पाठ-जिप समारोह है:

(defn stream-lessons-zip 
    [] 
    (let [lessons ...];... not shown 

    {:status 200 
    :headers {"Content-Type" "application/zip, application/octet-stream" 
      "Content-Disposition" (str "attachment; filename=\"files.zip\"") 
    :body (futil/zip-lessons lessons)})) 

और मैं एक पहुंचाया इनपुट धारा का उपयोग की तरह स्ट्रीमिंग करने के लिए इसलिए:

(defn zip-lessons 
"Returns an inputstream (piped-input-stream) to be used directly in Ring HTTP responses" 
[lessons] 
(let [paths (map #(select-keys % [:file_path :file_name]) lessons)] 
(ring-io/piped-input-stream 
    (fn [output-stream] 
    ; build a zip-output-stream from a normal output-stream 
    (with-open [zip-output-stream (ZipOutputStream. output-stream)] 
     (doseq [{:keys [file_path file_name] :as p} paths] 
     (let [f (cio/file file_path)] 
      (.putNextEntry zip-output-stream (ZipEntry. file_name)) 
      (cio/copy f zip-output-stream) 
      (.closeEntry zip-output-stream)))))))) 

तो मैं पुष्टि कर दी है 'सबक' वेक्टर 4 प्रविष्टियों की तरह होता है, जो है, लेकिन ज़िप फ़ाइल केवल 1 ई शामिल जाँचें। इसके अलावा, क्रोम डाउनलोड को 'अंतिम रूप देने' प्रतीत नहीं होता है, यानी। ऐसा लगता है कि यह अभी भी डाउनलोड हो रहा है।

मैं इसे कैसे ठीक कर सकता हूं?

+0

मैं closeEntry कॉल करने से पहले doseq में (.flush ज़िप उत्पादन-स्ट्रीम) जोड़ने की कोशिश की, लेकिन कोई लाभ नहीं हुआ। –

+1

मैंने आपके कोड के सरलीकृत संस्करण की कोशिश की और यह ठीक काम करता है। मुझे लगता है कि यह कुछ मध्यवर्ती समस्याएं पैदा कर सकता है। आप अपने ऐप को मध्यवर्ती के न्यूनतम या न्यूनतम सेट के साथ चलाने का प्रयास कर सकते हैं और देख सकते हैं कि यह काम करता है या नहीं। –

+1

क्या आप http-kit का उपयोग नहीं करते हैं? मुझे इसके साथ डाउनलोड स्ट्रीम करने की कोशिश करने में समस्याएं आई हैं, मुझे विश्वास नहीं है कि यह समर्थित है, जबकि यह रिंग-जेटी द्वारा है। – Russell

उत्तर

1

यह एक स्टेटफुल धारा अवरुद्ध आईओ का उपयोग कर उत्पादन http-किट द्वारा समर्थित नहीं है जैसा लगता है।

http://www.http-kit.org/server.html#async

एक पीआर स्टेटफुल धाराओं आईओ को अवरुद्ध का उपयोग कर लागू करने के लिए स्वीकार नहीं किया गया:

https://github.com/http-kit/http-kit/pull/181

यह की तरह लगता है पता लगाने के लिए विकल्प है गैर स्टेटफुल धाराओं इस तरह से किया जा सकता है ज़िप फ़ाइल को पूरी तरह से स्मृति में प्रस्तुत करने के लिए बाइटएरे ऑटपुटस्ट्रीम का उपयोग करें, और उसके बाद उत्पन्न बफर को वापस करें। यदि यह एंडपॉइंट अत्यधिक तस्करी नहीं है और ज़िप फ़ाइल जो उत्पादन करती है वह बड़ी नहीं है (< 1 जीबी) तो यह काम कर सकती है।