加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

在Clojure的Ring Web应用程序中生成并流式传输zip文件

发布时间:2020-12-14 16:39:02 所属栏目:资源 来源:网络整理
导读:我有一个需要的Ring处理程序: 压缩几个文件 将Zip流式传输到客户端. 现在我有点工作,但只有第一个压缩条目流式传输,然后停止/停止.我觉得它与刷新/流媒体有关,这是错误的. 这是我的(compojure)处理程序: (GET "/zip" {:as request} :query-params [order-i
我有一个需要的Ring处理程序:

>压缩几个文件
>将Zip流式传输到客户端.

现在我有点工作,但只有第一个压缩条目流式传输,然后停止/停止.我觉得它与刷新/流媒体有关,这是错误的.

这是我的(compojure)处理程序:

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

这是stream-lessons-zip函数:

(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个条目,但zip文件只包含1个条目.此外,Chrome似乎并未“完成”下载,即.它认为它仍在下载.

我怎样才能解决这个问题?

解决方法

听起来像http-kit不支持使用阻塞IO生成有状态流.非有状态流可以通过这种方式完成:

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

不接受使用阻塞IO引入有状态流的PR:

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

听起来,探索的选择是使用ByteArrayOutputStream将zip文件完全呈现到内存,然后返回生成的缓冲区.如果此端点没有高度流量,并且它生成的zip文件不大(<1 gb),那么这可能会起作用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读