我是 Clojure 新手。
我有一个 Clojure 应用程序,它在 http/s 上公开日志目录。但不幸的是,同一目录中还有一些其他文件。我只需要过滤带有 .log* 扩展名的文件。
我们有以下代码:
(defn get-dir-listing [dir]
(map #(get-all-attribs %) (fs/list-dir dir)))
(defn get-all-attribs [fpath]
{:type (if (fs/directory? fpath)
"Directory"
"File")
:name (.getName fpath)
:modtime (-> (fs/mod-time fpath)
time/from-long)
:size (-> (fs/size fpath)
get-size-in-KB)
})
我将其更改为以下内容:
(defn get-dir-listing [dir]
(map #(get-dirs-log-files-only %) (fs/list-dir dir)))
(defn get-dirs-log-files-only [fpath]
(if (and (not (fs/directory? fpath)) (.contains (.getName fpath) ".log"))
(get-all-attribs fpath)
(if (fs/directory? fpath)
(get-all-attribs fpath))))
(defn get-all-attribs [fpath]
{:type (if (fs/directory? fpath)
"Directory"
"File")
:name (.getName fpath)
:modtime (-> (fs/mod-time fpath)
time/from-long)
:size (-> (fs/size fpath)
get-size-in-KB)
})
;To remove nil
(remove nil? (get-dir-listing "C:\\tmp"))
有没有人有更好的方法来解决这个问题?
您可以将过滤文件的条件移至单独的函数中。这将更好地传达您要对列表执行的操作。然后,您可以使用
filter
应用这些标准。
此外,使用相关命名空间中的 Clojure 库函数而不是使用 Java 方法来处理字符串和文件被认为是更好的做法(例如,使用
clojure.string/includes?
而不是 String.contains
方法)。
(ns ...
:require [... [clojure.string :as cs]])
(defn is-log-or-dir? [fpath]
(or (fs/directory? fpath)
(cs/includes? (fs/base-name fpath) ".log")))
(defn get-dir-listing [dir]
(map get-all-attribs (filter is-log-or-dir? dir)))
这就是我所做的。可以通过扩展名或名称的任何其他部分进行过滤。这样就不需要检查文件是否是目录:
(过滤器 #(clojure.string/includes? (str %) ".log") (-> 外文件夹 clojure.java.io/file file-seq))