Java如何获取两个文件路径之间的中间层级文件序列
Java实现获取两个路径中间目录的优雅方案
Java 7及以上版本直接用自带的java.nio.file.Path API即可实现,不需要手动分割字符串处理路径分隔符、相对路径符号等边界问题,实现非常简洁:
核心逻辑
- 先将两个字符串路径转为Path对象,做标准化处理
- 校验基准路径是否是目标路径的父前缀,无包含关系直接返回空集合/抛异常
- 排除目标路径末尾的文件,从基准路径的下一层级开始逐层截取,得到所有中间目录
完整代码实现
import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class IntermediatePathUtil { /** * 获取两个路径之间的所有中间目录,返回绝对路径格式的List<Path>,可按需转为File或字符串 * @param basePathStr 基准父路径 * @param fullPathStr 完整子路径 * @return 中间目录集合,无包含关系返回空集合 */ public static List<Path> getIntermediateDirs(String basePathStr, String fullPathStr) { // 转成绝对路径并做标准化处理,自动处理.、..等相对路径符号 Path basePath = Paths.get(basePathStr).toAbsolutePath().normalize(); Path fullPath = Paths.get(fullPathStr).toAbsolutePath().normalize(); // 校验包含关系,无包含关系/两路径相等直接返回空 if (!fullPath.startsWith(basePath) || fullPath.equals(basePath)) { return Collections.emptyList(); // 如需抛异常替换为:throw new IllegalArgumentException("路径不存在包含关系"); } // 取目标路径的父目录,排除末尾的文件本身 Path fullDirPath = fullPath.getParent(); if (fullDirPath.equals(basePath)) { return Collections.emptyList(); } List<Path> result = new ArrayList<>(); int baseLevel = basePath.getNameCount(); int fullDirLevel = fullDirPath.getNameCount(); // 逐层截取中间路径 for (int i = baseLevel + 1; i <= fullDirLevel; i++) { Path relativeSubPath = fullDirPath.subpath(0, i); // 补全根路径,得到绝对路径 result.add(fullDirPath.getRoot().resolve(relativeSubPath)); } return result; } /** * 获取两个路径之间的所有中间目录,返回相对路径格式的List<String> * @param basePathStr 基准父路径 * @param fullPathStr 完整子路径 * @return 中间目录集合,无包含关系返回空集合 */ public static List<String> getIntermediateRelativeDirs(String basePathStr, String fullPathStr) { Path basePath = Paths.get(basePathStr).toAbsolutePath().normalize(); Path fullPath = Paths.get(fullPathStr).toAbsolutePath().normalize(); if (!fullPath.startsWith(basePath) || fullPath.equals(basePath)) { return Collections.emptyList(); } Path fullDirPath = fullPath.getParent(); if (fullDirPath.equals(basePath)) { return Collections.emptyList(); } List<String> result = new ArrayList<>(); int baseLevel = basePath.getNameCount(); int fullDirLevel = fullDirPath.getNameCount(); for (int i = baseLevel; i < fullDirLevel; i++) { result.add("/" + fullDirPath.getName(i) + "/"); } return result; } // 测试用例 public static void main(String[] args) { String basePath = "/opt/"; String fullPath = "/opt/tmp/some_dir_1/some_dir_2/file_1.txt"; // 输出[/opt/tmp, /opt/tmp/some_dir_1, /opt/tmp/some_dir_1/some_dir_2] System.out.println(getIntermediateDirs(basePath, fullPath)); // 输出[/tmp/, /some_dir_1/, /some_dir_2/] System.out.println(getIntermediateRelativeDirs(basePath, fullPath)); } }
实现优势
- 跨平台兼容,自动适配Windows、Linux等不同系统的路径分隔符
- 自动处理路径中的
.、..等相对路径符号,避免非法路径报错 - 原生API判断路径包含关系,不会出现字符串前缀匹配的误判(比如不会把
/opt1误判为/opt的子路径) - 自动兼容路径前后的多余斜杠,不需要手动做字符串trim处理
内容的提问来源于stack exchange,提问作者Bestows In Constructing
相关产品推荐
相关产品推荐

