如何解决需要帮助,使用Clojure下载和读取内存中的压缩CSV文件
我有一个外部站点,我想从该站点下载压缩的CSV文件。目前,我正在下载解压缩的文件,将其保存到磁盘,然后解压缩,将解压缩的文件保存至磁盘,然后使用CSV阅读器读取解压缩的文件。在此过程中,许多无用的步骤都可以清除,我继续这样做。
This amazing answer帮助我振作起来。我尝试使用链接到那里的第一个选项(GZIPInputStream
),但是出现“ Not GZIP format”错误,所以我想我必须转到第二个选项。
这是我当前的代码,它可以执行我想要的操作:
(defn download-zipped-stream!
(:body (clj-http.client/get "www.example.com" {:as :stream})))
(with-open
[stream (ZipInputStream. download-zipped-stream!)]
(.getNextEntry stream)
(doall (clojure.data.csv/read-csv (clojure.java.io/reader stream) :separator \;)))
我确实是通过反复试验来解决这个问题的。关于此代码,我主要想更改/了解三件事。
-
理想情况下,我想将代码分成两部分:一是下载并解压缩内容,然后返回流-原因是我想稍后决定是否直接将其作为csv读取。或写入磁盘(我不想丢失此选项,因为在开发过程中,读取预下载的csv文件比每次下载大型内容要容易得多)。事实证明,如果我尝试在
with-open
调用之外访问流,则会收到“流关闭”错误(据我所知,这是完全有道理的)。 -
在上面的代码中,我必须将此称为
.getNextEntry
,否则我将得到一个空列表。作为一个努力编写功能代码的人,这使我感到困扰,因为据我所知,我正在这里处理状态-我的流对象看起来是可变的,这是我真正想要的。难道没有办法解决此步骤,并在其中直截了当吗? -
我试图直接在
read-csv
对象上调用stream
方法,但是read-csv
显然并不真正知道如何处理ZipInputStreams。看到这一点,我简单而有希望地在两者之间抛出了一个io/reader
调用,并且它成功了。不过,我不知道这是否是最好的方法。正确吗?
我对Clojure还是很陌生,而且我对Java总体上一无所知,因此,如您所见,我对这些流对象的了解非常有限。我试图用Java阅读一些有关它的内容,但是我退出了,因为我不确定其中有多少对学习Clojure的人有用,所以任何指针也都值得赞赏。
解决方法
我认为您的做法是正确的。建议考虑:
-
考虑使用
wget
手动将*.csv.gz
文件下载到本地磁盘。然后,只需打开该本地文件,而不使用clj-http.client/get
。 -
我在ZipInputStream上玩的并不多,但是如果似乎需要使用
.getNextEntry()
,那就继续吧。 -
read-csv的示例显示了使用阅读器授予对输入文件的访问权限,因此这是预期的行为。
-
This template project显示了我如何组织Clojure项目和源代码。请务必仔细阅读所提供的文档列表。
-
不要忘记utilize cljdoc.org来查找Clojure库API文档。例如,请参见the API docs for data.csv。
更新
您可能还想查看this answer。
,可以将https://github.com/techascent/tech.ml.dataset与https://scicloj.github.io/tablecloth/index.html(TMD的api之类的dplyr)一起使用
SQL,Arrow等人也谈到过,该方法还具有非常快的优势,并且能够处理内存中无法容纳的数据集。等在此处加入有关此话题的讨论: https://clojurians.zulipchat.com/#narrow/stream/151924-data-science/topic/tech.2Eml.2Edataset
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。