假设我需要在 Clojure 中创建以下目录结构:
a
\--b
| \--b1
| \--b2
\--c
\-c1
而不是做如下程序性的事情:
(def a (File. "a"))
(.mkdir a)
(def b (File. a "b"))
(.mkdir b)
;; ...
...有没有一种聪明的方法可以以某种方式将上述动作以声明方式表示为数据,然后一口气创建层次结构?
假设我需要在 Clojure 中创建以下目录结构:
a
\--b
| \--b1
| \--b2
\--c
\-c1
而不是做如下程序性的事情:
(def a (File. "a"))
(.mkdir a)
(def b (File. a "b"))
(.mkdir b)
;; ...
...有没有一种聪明的方法可以以某种方式将上述动作以声明方式表示为数据,然后一口气创建层次结构?
一种快速简单的方法是制作一个 dirs 向量来创建 mkdir 并将其映射到它:
user> (map #(.mkdir (java.io.File. %)) ["a", "a/b" "a/b/c"])
(true true true)
或者您可以将您的 dir 结构指定为一棵树,并使用 zippers 来遍历它,从而在途中制作 dirs:
(def dirs ["a" ["b" ["b1" "b2"]] ["c" ["c1"]]])
(defn make-dir-tree [original]
(loop [loc (zip/vector-zip original)]
(if (zip/end? loc)
(zip/root loc)
(recur (zip/next
(do (if (not (vector? (zip/node loc)))
(let [path (apply str (interpose "/" (butlast (map first (zip/path loc)))))
name (zip/node loc)]
(if (empty? path)
(.mkdir (java.io.File. name))
(.mkdir (java.io.File. (str path "/" name))))))
loc))))))
(make-dir-tree dirs)
.
arthur@a:~/hello$ find a
a
a/c
a/c/c1
a/b
a/b/c
a/b/b2
a/b/b1
如果您正在做很多一般的系统管理,那么可能需要做一些更重的事情。托盘项目是一个库,用于在物理和云托管系统上进行各种系统管理(尽管它往往倾向于多云的东西)。具体目录
如果您想轻松处理创建递归目录,另一种选择是使用.mkdirs
user> (require '[clojure.java.io :as io]')
user> (.mkdirs (io/file "a/b/c/d"))
您可以使用绝对路径,例如。/a/b/c/d 否则它将相对于您启动 repl 的路径创建。
检查给定路径是否不是现有目录也很方便
user> (.isDirectory (io/file "a/b/c/d"))