在Clojure中的目录中列出文件

Mik*_*den 57 java clojure

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

ffr*_*end 96

使用file-seq功能.

用法示例:

(def directory (clojure.java.io/file "/path/to/directory"))
(def files (file-seq directory))
(take 10 files)
Run Code Online (Sandbox Code Playgroud)

  • `file-seq`本身就是`tree-seq`的一个很好的代码示例,它在访问任何分层数据结构时很有用. (4认同)
  • 从技术上讲,OP 并没有说他们想要递归列出文件,这(以及目录本身)是您将使用 `file-seq` 得到的。如果这不是他们想要的,`.listFiles` 加上对目录的检查是更好的选择。 (4认同)

rae*_*aek 30

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

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

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

.listFiles实例方法返回的数组的(可以作为SEQ使用)File对象-一个用于在由所识别的目录中的每个条目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. "."))
Run Code Online (Sandbox Code Playgroud)

构造文件对象

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

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

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


Chr*_*erg 14

还可以看看fs库.

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

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


Mic*_*ent 9

(use 'clojure.java.io)
(-> "/tmp" file .listFiles)
Run Code Online (Sandbox Code Playgroud)

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

(.listFiles (file "/tmp"))
Run Code Online (Sandbox Code Playgroud)


小智 8

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

列出目录的最简单方法:

(seq (.list (clojure.java.io/file ".")))
Run Code Online (Sandbox Code Playgroud)

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

(map #(.getPath %)
     (file-seq (clojure.java.io/file ".")))
Run Code Online (Sandbox Code Playgroud)


小智 6

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

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