22 June 2024

之前介绍过babashka - 有趣又便捷巴布什卡头巾,用 clojure 处理脚本任务方便又快捷,还有很多上手能用的内置函数库可以用。

一般脚本处理,文件操作是必不可少的任务。这篇文章介绍下 babashka 的文件系统库。

首先要用过 require 把函数库加载进来。然后,我们定义一组文件路径进行测试。

(require '[babashka.fs :as fs])
(def test-paths
  ["."  ;; 相对路径
   ".." ;; 相对路径,隐藏文件
   "~"  ;; 当作普通文件名处理,所以是该文件不存在
   "bb" ;; 可执行文件,不可写
   "babashka-fs.org" ;; 本文,文本文件
   "/"  ;; 根目录
   "/Users/kimim/babashka" ;; 本文上层目录
   "/Users/kimim/babashka/babashka-fs.org" ;; 本文绝对路径
   "/opt/homebrew/bin/bb" ;; bb 的符号链接文件,可执行
   ])
#'user/test-paths

然后,检查下,我们的操作系统是不是 Windows

(fs/windows?)
false

因为,现在用的是 macOS ,所以返回结果为 false。

检查文件路径是不是绝对路径

(doseq [path test-paths]
  (print (str "\"" path "\":")
         (fs/absolute? path) "\n"))
".": false 
"..": false 
"~": false 
"bb": false 
"babashka-fs.org": false 
"/": true 
"/Users/kimim/babashka": true 
"/Users/kimim/babashka/babashka-fs.org": true 
"/opt/homebrew/bin/bb": true

只有/开头的路径才是绝对路径。如果是绝对路径,fs/absolute?返回 true ,不然返回 false

是否为相对路径

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/relative? path) "\n"))
"." true 
".." true 
"~" true 
"bb" true 
"babashka-fs.org" true 
"/" false 
"/Users/kimim/babashka" false 
"/Users/kimim/babashka/babashka-fs.org" false 
"/opt/homebrew/bin/bb" false

也就是fs/absolutizefs/relative? 是一对互补查询函数。

检查文件是否存在

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/exists? path) "\n"))
"." true 
".." true 
"~" false 
"bb" false 
"babashka-fs.org" false 
"/" true 
"/Users/kimim/babashka" true 
"/Users/kimim/babashka/babashka-fs.org" false 
"/opt/homebrew/bin/bb" true

注意 babashka/fs 不把波浪线当作特殊字符处理。

需要fs/expand-home把波浪线转成系统的user.home环境变量。

(str (fs/expand-home "~"))
/Users/kimim

检查文件是否为文件夹

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/directory? path) "\n"))
"." true 
".." true 
"~" false 
"bb" false 
"babashka-fs.org" false 
"/" true 
"/Users/kimim/babashka" true 
"/Users/kimim/babashka/babashka-fs.org" false 
"/opt/homebrew/bin/bb" false

是否可执行

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/executable? path) "\n"))
"." true 
".." true 
"~" false 
"bb" false 
"babashka-fs.org" false 
"/" true 
"/Users/kimim/babashka" true 
"/Users/kimim/babashka/babashka-fs.org" false 
"/opt/homebrew/bin/bb" true

是否隐藏文件

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/hidden? path) "\n"))
"." true 
".." true 
"~" false 
"bb" false 
"babashka-fs.org" false 
"/" false 
"/Users/kimim/babashka" false 
"/Users/kimim/babashka/babashka-fs.org" false 
"/opt/homebrew/bin/bb" false

是否可读取

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/readable? path) "\n"))
"." true 
".." true 
"~" false 
"bb" true 
"babashka-fs.org" true 
"/" true 
"/Users/kimim/babashka" true 
"/Users/kimim/babashka/babashka-fs.org" true 
"/opt/homebrew/bin/bb" true

是否可写

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/writable? path) "\n"))
"." true 
".." true 
"~" false 
"bb" false 
"babashka-fs.org" true 
"/" false 
"/Users/kimim/babashka" true 
"/Users/kimim/babashka/babashka-fs.org" true 
"/opt/homebrew/bin/bb" false

是否符号连接

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (fs/sym-link? path) "\n"))
"." false 
".." false 
"~" false 
"bb" false 
"babashka-fs.org" false 
"/" false 
"/Users/kimim/babashka" false 
"/Users/kimim/babashka/babashka-fs.org" false 
"/opt/homebrew/bin/bb" true

把文件路径变成绝对路径

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (str (fs/absolutize path)) "\n"))
"." /Users/kimim/babashka/. 
".." /Users/kimim/babashka/.. 
"~" /Users/kimim/babashka/~ 
"bb" /Users/kimim/babashka/bb 
"babashka-fs.org" /Users/kimim/babashka/babashka-fs.org 
"/" / 
"/Users/kimim/babashka" /Users/kimim/babashka 
"/Users/kimim/babashka/babashka-fs.org" /Users/kimim/babashka/babashka-fs.org 
"/opt/homebrew/bin/bb" /opt/homebrew/bin/bb

fs/absolutize 返回文件对象sun.nio.fs.UnixPath,为了显示清晰,我们把它转成字符串输出。

把文件路径正规化

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (str (fs/canonicalize path)) "\n"))
"." /Users/kimim/babashka 
".." /Users/kimim 
"~" /Users/kimim/babashka/~ 
"bb" /Users/kimim/babashka/bb 
"babashka-fs.org" /Users/kimim/babashka/babashka-fs.org 
"/" / 
"/Users/kimim/babashka" /Users/kimim/babashka 
"/Users/kimim/babashka/babashka-fs.org" /Users/kimim/babashka/babashka-fs.org 
"/opt/homebrew/bin/bb" /opt/homebrew/Cellar/babashka/1.3.190/bin/bb

把文件路径变成 Unix 风格的路径

(doseq [path test-paths]
  (print (str "\"" path "\"")
         (str (fs/unixify path)) "\n"))
"." . 
".." .. 
"~" ~ 
"bb" bb 
"babashka-fs.org" babashka-fs.org 
"/" / 
"/Users/kimim/babashka" /Users/kimim/babashka 
"/Users/kimim/babashka/babashka-fs.org" /Users/kimim/babashka/babashka-fs.org 
"/opt/homebrew/bin/bb" /opt/homebrew/bin/bb