首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
281 阅读
2
从零开始配置 vim(15)——状态栏配置
165 阅读
3
nvim番外之将配置的插件管理器更新为lazy
157 阅读
4
2018总结与2019规划
144 阅读
5
PDF标准详解(五)——图形状态
119 阅读
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
登录
Search
标签搜索
c++
c
学习笔记
windows
emacs
文本操作术
elisp
编辑器
NeoVim
Vim
win32
读书笔记
VimScript
linux
文本编辑器
投资理财
Java
反汇编
OLEDB
数据库编程
Masimaro
累计撰写
426
篇文章
累计收到
32
条评论
首页
栏目
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
页面
归档
友情链接
关于
搜索到
1
篇与
的结果
2026-09-07
《elisp 每日一练》——文件属性
很抱歉,因为上个周末有一些事情要处理所以停更了两天。现在我们恢复更新。在之前我们介绍了文件读写的一些api,以及使用 with-temp-buffer 和 insert-file-content 实现低成本的文件读取。今天我们来介绍文件属性相关的内容背景知识铺垫文件属性获取到的信息与其他编程语言获取文件信息类似,我将它分为以下几种属性的操作:路径解析这类api我们需要传入一个无歧义的文件路径,但是路径可以不必真实存在。expand-file-name 将相对路径或者带有 ~ 家目录字符的路径转化为绝对路径file-name-directory 获取参数传入的文件路径所在的目录file-name-nondirectory 去掉文件路径中的目录,得到单纯的文件名file-name-extension 获取文件的扩展名file-name-concat 路径拼接路径拼接这部分,我们可以使用 expand-file-name 或者 file-name-concat,在Emacs 28以后推荐使用 file-name-concat 。它可以将传入的多个路径参数转化为一个完整的目录, 例如(file-name-concat "~" ".emacs.d" "init.el") ;; ==> ~/.emacs.d/init.el (expand-file-name "init.el" "~/.emacs.d") ;; ==> C:/Users/user/AppData/Roaming/.emacs.d/init.elexpand-file-name 最多只能接受两个参数,第一个参数是文件的相对路径,而第二个参数是文件所在目录的路径。从上面的例子中可以看出,file-name-concat 缺少了一个转化 ~ 字符的功能。对于Windows上来讲,有时候使用 ~ 作为家目录可能会出现问题,虽然环境变量中已经给出了家目录但是,Emacs真正在读取对应文件时不一定认,所以最好的办法是使用 expand-file-name 转化为Windows上的绝对路径文件状态与断言函数在获取文件之前我们可以快速的对上述文件路径进行快速校验:file-exists-p 文件或者目录是否存在file-regular-p 是否为普通文件,排除目录、符号链接、Socket等特殊文件file-symlink-p 是否为符号链接,如果是,则返回链接指向的真实文件的路径file-readable-p / file-writeable-p 文件是否具有读写权限文件属性读取当我们确认了文件真实存在之后就可以调用函数 file-attributes 获取文件的真实属性了。函数签名如下:(file-attributes FILENAME &optional ID-FORMAT)FILENAME 这个参数比较好理解,就是一个文件路径的字符串。我们需要重点关注一下 ID-FORMAT 这个参数。ID-FORMAT 参数用于控制返回的文件属主(UID)和属组(GID)信息的格式。它接受两个特定的符号作为值:integer 默认值,返回数字类型的用户ID和用户组IDstring 以字符串的形式尽量返回详细的用户名和用户组名我们以具体的例子来讲解(let ((file (expand-file-name "init.el" "~/.emacs.d"))) (message "%s" (file-attributes file 'string)))我们得到这样一个返回值(nil 1 user user (27294 6305 0 0) (27286 33330 0 0) (27258 57596 0 0) 1034 -rw-rw-rw- t 17451448556305724 1353222740)列表的第0个元素表示类型,t 代表着这是一个目录, nil 表示这是一个文件第1个元素表示链接数第2个和第3个表示用户和用户组,因为我们的 ID-FORMAT 指定了 'string 所以它以字符串的形式显示名称第4、5、6是一个时间戳,表示最后访问时间、最后修改时间和状态最后被修改的时间第7个元素是文件大小,单位是字节第8个元素是文件权限第9个元素是inode 节点第10个元素是设备标识符三个时间戳都是以 (SECOND MICROSECOND PICONANOSECOND PICONANOSECOND) 列表格式返回的,对这个时间戳可以使用 format-time-string 来将其转化为人类可以读的字符串(let* ((file (expand-file-name "init.el" "~/.emacs.d")) (attribute (file-attributes file 'string))) (message "last modified:%s" (format-time-string "%Y-%m-%d %H:%M:%S" (nth 5 attribute)))) ;; ==> "last modified:2026-09-01 15:43:46"既然上述信息都是固定的,那么我们就可以封装一些意义更明确的函数,例如 get-file-attribute-mode 之类的函数从返回的属性列表中获取文件权限信息。这个工作Emacs已经为我们做了,针对属性中的内容 Emacs 有一组以 file-attribute- 开头的函数,我们可以使用 C-h f 查看这一组函数练习我们使用上述知识点做一个练习,以 ls 的格式输出文件详细属性信息。(defun my/format-file-attributes (file-path) (let ((abs-file-path (expand-file-name file-path))) (if (not (file-exists-p abs-file-path)) (error "File :%s not exists" abs-file-path) (let* ((attrs (file-attributes abs-file-path 'string)) (modes (file-attribute-modes attrs)) (owner (file-attribute-user-id attrs)) (group (file-attribute-group-id attrs)) (size (file-attribute-size attrs)) (modified-time (format-time-string "%Y-%m-%d %H:%M:%S" (file-attribute-modification-time attrs))) (filename (file-name-nondirectory abs-file-path))) (format "%-11s %-8s %-8s %8d Bytes %s %s" modes owner group size modified-time filename))))) (defun my/show-file-attributes(file-name) (interactive "fFile Path:") (let ((buffer (generate-new-buffer "FileAttribute")) (attr-message (my/format-file-attributes file-name))) (switch-to-buffer buffer) (erase-buffer) (goto-char (point-min)) (insert attr-message)))总结本篇我们介绍了有关文件属性的一些函数,今天介绍的主要函数有:expand-file-name 将相对路径或者带有 ~ 家目录字符的路径转化为绝对路径file-name-directory 获取参数传入的文件路径所在的目录file-name-nondirectory 去掉文件路径中的目录,得到单纯的文件名file-name-extension 获取文件的扩展名file-name-concat 路径拼接file-exists-p 文件或者目录是否存在file-regular-p 是否为普通文件,排除目录、符号链接、Socket等特殊文件file-symlink-p 是否为符号链接,如果是,则返回链接指向的真实文件的路径file-readable-p / file-writeable-p 文件是否具有读写权限file-attributes 读取文件或者目录的属性关于属性读取,我们可以使用 nth 加上索引来获取列表中的内容,也可以调用 file-attribute 开头的一组函数来获取。
2026年09月07日
0 阅读
0 评论
0 点赞