在Clojure中的目录中列出文件

时间:2011-12-19 19:39:02

标签: java clojure

如何在Clojure中的特定目录中的所有文件中创建列表?我是否不得不求助于调用Java或者Clojure可以原生地处理这个问题吗?

7 个答案:

答案 0 :(得分:93)

使用file-seq功能。

用法示例:

(def directory (clojure.java.io/file "/path/to/directory"))
(def files (file-seq directory))
(take 10 files)

答案 1 :(得分:30)

Clojure旨在拥抱Java平台,这是Clojure不提供自己的API的一个领域。这意味着你可能不得不深入研究Java,但你必须使用的类可以直接从Clojure中使用。

您应该在javadocs中阅读的一个类是java.io.File,它代表文件路径

http://docs.oracle.com/javase/6/docs/api/java/io/File.html

.listFiles实例方法返回File个对象的数组(可以用作seq) - 一个用于File实例标识的目录中的每个条目。还有其他有用的方法可用于确定File是否存在,是否为目录等。

实施例

(ns my-file-utils
  (:import java.io.File))

(defn my-ls [d]
  (println "Files in " (.getName d))
  (doseq [f (.listFiles d)]
    (if (.isDirectory f)
      (print "d ")
      (print "- "))
    (println (.getName f))))

;; Usage: (my-ls (File. "."))

构建文件对象

File的构造函数有时候使用起来有点不方便(特别是在一次合并多个路径段时),在这种情况下,Clojure提供了一个有用的辅助函数:clojure.java.io/file。作为其参数,它接受路径段作为字符串或文件。这些段与平台的正确路径分隔符连接。

http://clojuredocs.org/clojure_core/clojure.java.io/file

注意:Clojure还提供了file-seq函数,该函数通过从给定文件开始的文件层次结构返回前序步行(作为seq)。

答案 2 :(得分:14)

另请查看fs library

如果您只需要一个目录中的文件列表,那么可能不值得提取额外的依赖项,但是那里有许多有用的实用程序函数,例如:

  • 创建目录结构
  • 复制,删除,移动
  • 检查和更改权限
  • 分割和规范化路径
  • 创建临时文件和目录
  • 通配
  • 使用zip和tar文件

答案 3 :(得分:9)

(use 'clojure.java.io)
(-> "/tmp" file .listFiles)

后一个表达式是从方法listFiles返回的File-objects数组,在从路径“/ tmp”创建的文件对象上调用。这是一种奇特的写作方式:

(.listFiles (file "/tmp"))

答案 4 :(得分:8)

通常,当我们说要列出目录时,我们的意思是我们想要获取文件名或路径,所以 - >

列出目录的最简单方法:

(seq (.list (clojure.java.io/file ".")))

如果要以递归方式列出,则:

(map #(.getPath %)
     (file-seq (clojure.java.io/file ".")))

答案 5 :(得分:6)

要使修改后的代码与原始示例代码的功能相匹配,您应该添加调用以获取文件名,如下所示。

(def directory (clojure.java.io/file "/path/to/directory"))
(def files 
    (for [file (file-seq directory)] (.getName file)))
(take 10 files)

答案 6 :(得分:0)

一个宏,用于以递归方式或仅在父目录中列出目录中的文件。它还可以搜索带有特定结尾扩展名的文件。

    ;; lists all the files recursively inside the directory passed as d like "."
(defmacro my-rec-list
  "generate the recursive list" {:added "1.0"}
  [d str rec]
  `(->> ~d
       clojure.java.io/file
       ~(if (= rec "rec")
          `file-seq
          `(.listFiles)) 
       ~(cond 
          (= str "file")  `(filter #(.isFile %))
          (= str "dir")   `(filter #(.isDirectory %))
          :always         `(filter #(.matches (.getPathMatcher 
                          (java.nio.file.FileSystems/getDefault)
                          ~str) (.getFileName (.toPath %)))))
       (mapv #(.getAbsolutePath %))))


(defn my-rec-ls-file 
  "generate the recursive list for only files in a directory"
  [d ] 
  (my-rec-list d "file" "rec"))
(defn my-rec-ls-dir 
  "generate the recursive list for only directory"
  [d ] 
  (my-rec-list d "dir" "rec"))
(defn my-rec-ls-jpg 
  "generate the recursive list for files and directory"
  [d ] 
  (my-rec-list d "glob:*.jpg" "rec"))
(defn my-ls-file 
  "generate the recursive list for only files in a directory"
  [d ] 
  (my-rec-list d "file" "norec"))
(defn my-ls-dir 
  "generate the recursive list for only directory"
  [d ] 
  (my-rec-list d "dir" "norec"))
(defn my-ls-jpg 
  "generate the recursive list for files and directory"
  [d ] 
  (my-rec-list d "glob:*.jpg" "norec"))

它导致不同的功能,可以通过目录调用该函数以递归或非递归的方式获取文件列表,目录或匹配的扩展文件。 例子是-

(def directory (clojure.java.io/file "/Path/to/Directory"))
(my-rec-ls-jpg directory) ;; find all jpg file recessively in directory
(my-ls-jpg directory) ;; find jpg file in current directory