files.getattribute 在 linux/macos 上无法可靠读取文件创建时间,因系统不维护该属性;windows 和部分 ext4 可支持,但需特定命名空间和配置。

Files.getAttribute 能否读取文件创建时间?
在绝大多数 Linux 和 macOS 系统上,Files.getAttribute 无法可靠获取「创建时间(creation time)」,因为这些系统本身不维护该属性——只有 Windows NTFS 和部分新版 ext4(需启用 birthtime 挂载选项)才支持。Java 的 BasicFileAttributes 接口只定义了 creationTime(),但底层实现可能返回一个占位值(如 Unix 上常退化为最后修改时间或 1970-01-01)。实际调用时不会抛异常,但结果不可信。
如果你真需要创建时间,得换路子:
– Windows:用 Files.readAttributes(path, "dos:creationTime") 或 "win:creationTime"(取决于 JDK 版本)
– Linux/macOS:基本无解,除非文件系统+内核+JDK 全栈支持 birthtime(JDK 11+ 对 ext4 的 unix:birthtime 有实验性支持,但需手动启用)
用 Files.getAttribute 读取权限(POSIX 权限)的正确姿势
Unix/Linux/macOS 下权限必须用 PosixFileAttributes,不能依赖 BasicFileAttributes。常见错误是直接传 "basic:permissions"——这会失败,因为权限不是 basic 层级的属性。
正确做法:
- 调用
Files.readAttributes(path, PosixFileAttributes.class),再调用.permissions()方法 - 或用字符串形式:
Files.getAttribute(path, "posix:permissions"),返回的是Set<posixfilepermission></posixfilepermission> - 注意:路径必须指向真实文件/目录,且 JVM 进程有读取其元数据的权限(例如不能跨挂载点读取某些 NFS 或容器绑定卷)
示例:
Set<posixfilepermission> perms = (Set<posixfilepermission>) Files.getAttribute(path, "posix:permissions");</posixfilepermission></posixfilepermission>返回类似
[OWNER_READ, OWNER_WRITE, GROUP_READ, OTHERS_READ]
Windows 下读取 DOS 属性(只读、隐藏、系统等)
Windows 文件有额外的 DOS 属性,Java 提供了 dos: 命名空间支持。但要注意:这些属性和 POSIX 权限互不兼容,跨平台代码里不能混用。
可用属性名包括:dos:readonly、dos:hidden、dos:system、dos:archive,返回类型是 Boolean。
示例:
Boolean isReadOnly = (Boolean) Files.getAttribute(path, "dos:readonly");如果文件不在 Windows 上,该调用会抛
UnsupportedOperationException,不是静默返回 null。
安全写法是先检查 OS:
if (System.getProperty("os.name").toLowerCase().contains("win")) { ... }
为什么 getAttribute("basic:creationTime") 总是返回奇怪的时间?
这是最常踩的坑:你以为在读创建时间,其实只是 BasicFileAttributes.creationTime() 的契约式兜底行为。JVM 在 Unix 平台会把 st_ctime(状态变更时间,即 chmod/chown/mv 等元数据修改时间)当作 creationTime 返回——它根本不是「文件诞生那一刻」的时间。
验证方法:
touch file && sleep 1 && chmod +x file然后用
Files.readAttributes(path, BasicFileAttributes.class).creationTime(),你会发现时间戳变了——这就是 st_ctime 的表现。
真正想对齐用户认知里的“创建时间”,要么放弃跨平台(Windows 专用路径),要么接受现实:Unix 类系统没有这个概念,别硬套。
权限和时间这类属性,底层依赖操作系统 API 和文件系统能力,Java 只是薄封装。没看到文档明确说「支持」,就别默认它存在。










