Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 从zip文件中惰性地读取每个条目_Clojure - Fatal编程技术网

Clojure 从zip文件中惰性地读取每个条目

Clojure 从zip文件中惰性地读取每个条目,clojure,Clojure,如果可能的话,我想将zip文件中的文件条目读入字符串序列。目前我正在做类似的事情来打印目录名,例如: (defn entries [zipfile] (lazy-seq (if-let [entry (.getNextEntry zipfile)] (cons entry (entries zipfile))))) (defn with-each-entry [fileName f] (with-open [z (ZipInputStrea

如果可能的话,我想将zip文件中的文件条目读入字符串序列。目前我正在做类似的事情来打印目录名,例如:

 (defn entries [zipfile]
   (lazy-seq
       (if-let [entry (.getNextEntry zipfile)]
            (cons entry (entries zipfile)))))


(defn with-each-entry [fileName f]
   (with-open [z (ZipInputStream. (FileInputStream. fileName))]
       (doseq [e (entries z)]
            ; (println (.getName e))
            (f e)
            (.closeEntry z))))

(with-each-entry  "tmp/my.zip"
  (fn [e] (if (.isDirectory e)
            (println (.getName e)))))
但是,这将遍历整个zip文件。我怎样才能改变这一点,使我能够接受前几个条目,比如:

(take 10 (zip-entries "tmp/my.zip"
  (fn [e] (if (.isDirectory e)
            (println (.getName e)))))

这似乎是非常自然的适合。
您只需使用
comp
和不带seq/collection参数的常用seq-transforming fn来构建作为传感器的变换。在您的示例中,
(comp(map#(.getName%))(取10%)

(comp(filter#(.isDirectory%))(map#(>%.getName println))

这将返回一个具有多个算术的函数,您可以通过多种方式使用该函数。在这种情况下,您希望在条目序列上减少它(以确保条目的实现在带有open的
内部进行),因此您使用
transduce
(通过压缩我的clojure项目文件夹之一生成的示例zip数据):

这里我用基函数conj进行转换,它构成了一个名称向量。如果您希望传感器执行副作用而不返回值,则可以使用基本功能,如
(常为零)

其输出:

target/
target/classes/
target/stale/
test/

这样做的一个潜在缺点是,您可能必须手动将
.closeEntry
调用合并到您在此处使用的每个转换器中,以防止占用这些资源,因为在一般情况下,您无法知道每个转换器何时读取完条目。

条目
是惰性的,那么
(映射f条目)如何
?因为这样,您很可能会得到一个部分实现的结果,该结果会逃过带有open
块的
,如果您试图延迟实现进一步的结果,则会导致错误。懒惰和时间有限的资源不能很好地结合在一起。选项是急切地使用资源(如这里所做的),或者在使用lazy-seq时手动回收资源,这看起来非常有趣。我将尝试它,如果它的工作方式,我希望标记它正确。谢谢
(with-open [z (-> "training-day.zip" FileInputStream. ZipInputStream.)]
  (let[transform (comp (filter #(.isDirectory %)) (map #(-> % .getName  println)))]
    (transduce transform (constantly nil) (entries z))))
target/
target/classes/
target/stale/
test/