filesystemexception报错原因需看message字段:含“access is denied”等为权限问题,含路径过长提示则为路径超限;windows下可用\?前缀绕过260字符限制,但须paths.get()显式构造且仅支持绝对路径。

FileSystemException 报错到底是因为权限还是路径?
直接看 FileSystemException 的 message 字段——它几乎从不模糊。如果含 "Access is denied" 或 "Permission denied",就是权限问题;如果含 "The specified path, file name, or both are too long"(Windows)或 "File name too long"(Linux/macOS),就是路径超长。别猜,先读错信息。
Windows 下路径过长怎么绕过去?
Java 本身不处理 Windows 路径长度限制(MAX_PATH=260),这是 NTFS 和 Win32 API 层的硬限制。JDK 11+ 默认启用 \? 前缀支持,但仅限于你显式使用 Paths.get() 构造时传入带前缀的字符串。
- 正确写法:
Paths.get("\\?\C:\very\long\path\to\file.txt") - 错误写法:
new File("C:\very\long\path...").toPath()——File类会自动截断或丢弃前缀 - 注意:
\?只对绝对路径有效,且不支持相对路径、..、通配符 - JVM 启动参数
-Djdk.io.permissionsUseCanonicalPath=false与此无关,别乱加
权限被拒时,到底是哪一层拦住了?
Java 的 Files.createDirectory() 或 Files.write() 失败,未必是目标目录没写权限——更常见的是父目录不可遍历(execute 权限缺失)。Linux/macOS 上,要进入一个目录必须有 x 权限;Windows 上对应的是“遍历文件夹/执行文件”权限位。
- 检查命令:
ls -ld /parent/dir(Linux/macOS),看是否有x;Windows 用icacls "C:parentdir" -
Files.createDirectories()会逐级创建,但如果中间某级只有写权限、没有执行/遍历权限,就会在那层抛FileSystemException - 不要依赖
SecurityManager(已废弃),它不参与底层文件系统权限校验 - 容器环境(如 Docker)中,挂载卷的 UID/GID 不匹配也会表现为“权限拒绝”,和宿主机实际 ACL 无关
为什么 try-with-resources + Files.newOutputStream 还是报 FileSystemException?
因为 Files.newOutputStream() 是懒加载——它只校验路径合法性与父目录可写性,不真正打开文件;真正触发磁盘 I/O 和完整权限检查,是在第一次 write() 或 flush() 时。所以即使 try 块里没写数据,只要流没 close,异常也可能延迟抛出。
立即学习“Java免费学习笔记(深入)”;
- 典型误判:以为
newOutputStream()成功 = 文件一定能写,其实不是 - 避免方式:在 try 块内至少执行一次
out.write(new byte[0])或out.flush(),提前暴露问题 - 注意:
StandardOpenOption.CREATE_NEW要求文件**不能存在**,若存在会直接报"File already exists",这也属于FileSystemException子类
sun.nio.fs.WindowsException 或 UnixException 底层封装后统一抛成 FileSystemException。错在哪一层,得靠 message 和上下文定位,不能只看异常类型名。










