Java NIO Path遍历目录读取WindowsApps下0字节EXE属性报错,求这类文件的相关信息
特殊文件的实际本质
你在C:\Users\<用户名>\AppData\Local\Microsoft\WindowsApps\路径下碰到的5个0字节EXE文件,是Windows系统自带的应用执行别名(App Execution Aliases),既不是硬链接、符号链接,也不是junction联接:
- 这类对象不是存储在磁盘上的真实文件,是系统通过虚拟文件系统驱动生成的特殊程序入口,作用是给UWP/微软商店安装的应用生成可直接在命令行唤起的执行别名,你提到的
GameBarElevatedFT_Alias.exe就是Xbox Game Bar对应的系统级别名入口。 - 因为它不属于NTFS传统的链接类型,所以你用
dir /AL(列出所有链接类文件)看不到SYMLINK、JUNCTION标识,attrib这类常规系统命令也读不到它的常规属性。 - 这类对象自带系统级权限隔离:普通进程哪怕拿到完整路径,只要没有对应系统权限,连基本的文件元数据(大小、创建时间等)都无法读取,这就是你用Java NIO读属性时报"无法被系统访问"错误的直接原因。
- 你自己创建的0字节EXE和它本质完全不同:自建文件是真实存在于磁盘上的空文件,所有系统API都可以正常读取属性,所以旧的
java.io.File遍历逻辑、常规命令行工具都能正常识别处理。
两种Java遍历实现的表现差异来源
- 你之前基于
java.io.File的遍历逻辑,是通过File.list()获取目录下的文件名列表,这个操作只需要读取目录项的文件名索引,不需要打开每个文件、也不需要查询文件属性,所以哪怕碰到这类受保护的虚拟别名,也能顺利拿到文件名,不会触发权限校验报错。 - 你现在改用NIO写的遍历逻辑,是拿到每个文件的Path后直接调用
Files.readAttributes()查询基础属性,这个操作会触发系统的文件权限校验,碰到带权限隔离的虚拟别名时就会直接抛出IO异常。这不是NIO本身的实现问题,是这类系统特殊对象的权限设计导致的。
关于验证NIO遍历性能的参考
- 你当前的实现并没有真正发挥NIO的性能优势:现在还是靠
File.list()拿文件名列表,之后才转成Path查属性,和传统IO的系统调用路径差异很小,很难测出明显的速度差。 - 如果要真实对比遍历性能,可以直接用NIO原生的遍历API,比如
Files.walkFileTree()、Files.list(),这类API遍历目录时会批量获取目录项的基础属性,不需要为每个文件单独发起一次属性查询的系统调用,在大目录下的遍历速度提升会非常明显。 - 遍历这类带系统特殊文件的目录时,记得在属性查询逻辑里加异常捕获,把读不到属性的对象单独标记记录,不要让单个特殊文件中断整个递归遍历流程。
内容的提问来源于stack exchange,提问作者arcy
相关产品推荐
相关产品推荐

