px普贤教程PuXian
普贤教程 › 生态包

文件系统

文件系统这一组:glob 通配、shutil 拷贝移动、walk 遍历、fsnotify 变更监听、tempfile 临时文件、dirs 标准目录。

通配与列举

px
import glob

print(glob_match("*.px", "gen.px"))            # true
print(glob_match("src/**/*.px", "src/a/b.px")) # true
print(glob_list("/data/work/px-tutorial-20261105/gen", "*.px"))
# Ok([/data/work/px-tutorial-20261105/gen/gen.px])
glob_list 返回 Ok(路径列表),不是裸 list;目录不存在返回 Err。写清理脚本时先判 is_err(),别把「目录不存在」当成「没有文件」——后者会让你以为已经干净了。

文件操作

px
import shutil

sh_mkdirs("/tmp/demo/a/b")
sh_write_text("/tmp/demo/a/x.txt", "hello")
print(sh_read_text("/tmp/demo/a/x.txt"))    # hello
sh_copy("/tmp/demo/a/x.txt", "/tmp/demo/a/y.txt")
sh_move("/tmp/demo/a/y.txt", "/tmp/demo/z.txt")
print(sh_list_files("/tmp/demo/a"))         # [x.txt]
sh_remove_tree("/tmp/demo")
sh_remove_tree 是递归删除脚本里对路径参数做任何拼接前,先确认它不是空串、不含 ..、不在 / 或家目录上。删除类操作在服务端一律先 print 出「将要删的绝对路径」再做。

标准目录

px
import dirs

print(dr_home())              # /root
print(dr_config())            # /root/.config
print(dr_data())              # /root/.local/share
print(dr_cache())             # /root/.cache
print(dr_app_data("demo"))    # /root/.local/share/demo
print(dr_pjoin(["a", "b"]))   # a/b

遵循 XDG 规范:配置、数据、缓存分开放。部署脚本里别再硬编码 /root/.xxx —— 换用户或换系统就坏。

遍历

px
import walk

walk_dir("/data/www", def(path, is_dir):
    if not is_dir and ends_with(path, ".html"):
        print(path)
)

回调式遍历,不一次性把整棵树读进内存。大目录(几万文件)用它,别用 glob_list 拼 **。

变更监听

px
import fsnotify

var w = fs_watch_new("/etc/nginx", "*.conf", 5)   # 5 秒轮询间隔
loop:
    var ch = fs_watch_poll(w)
    for p in ch:
        print("changed: " + p)
    sleep_ms(1000)
它是轮询快照,不是 inotify机制是「定期 stat 比对」,所以:① 有最长一个轮询间隔的延迟;② 文件多时开销随文件数增长;③ 进程重启期间的变更会漏掉(重启要重建基线)。要零延迟用 inotify(系统工具),要「配置改了自动 reload」这种场景它正好够。

临时文件

px
import tempfile

var d = tf_tempdir("px-")          # 建临时目录
var f = tf_tempname_ext(".json")   # 只要名字
tf_write(f, "{}")
tf_cleanup(d)                      # 清理

临时文件写在 $TMPDIR(默认 /tmp)。注意 /tmp 常被 tmpfs 或定期清理:跨重启要保留的东西别放这里。

文件操作的纪律

  • 先判存在再读:exists(p) 或 read_file_opt;read_file 遇到不存在会抛错。
  • 写文件用 write_file,二进制用 write_bytes:write_file 对 bytes 会写成 <bytes N> 字符串。
  • 大文件分块:write_all 一次写超过 16 MiB 会挂死(实测)。
  • 路径拼接用 dr_pjoin,别手拼 /——尾部斜杠重复会变成 //,某些场景下语义不同。