文章目录
- [358. Java IO API - 使用 `relativize()` 创建路径之间的相对关系](#358. Java IO API - 使用
relativize()创建路径之间的相对关系) -
-
- [🧠 方法语法](#🧠 方法语法)
- [✅ 示例 1:兄弟路径(sibling paths)](#✅ 示例 1:兄弟路径(sibling paths))
- [✅ 示例 2:父子路径](#✅ 示例 2:父子路径)
- [❗ 注意事项](#❗ 注意事项)
- [💡 实际应用:构造目标路径](#💡 实际应用:构造目标路径)
- [🧾 总结表](#🧾 总结表)
- [📌 小技巧](#📌 小技巧)
-
358. Java IO API - 使用 relativize() 创建路径之间的相对关系
在编写文件 I/O 代码时,一个常见的需求是:从路径 A 到路径 B 的"相对路径"是什么?
Java 提供了 Path.relativize() 方法,用于构造一个从当前路径出发,到达目标路径的相对路径。
🧠 方法语法
java
Path relativePath = basePath.relativize(targetPath);
- 它返回一个
Path,表示从basePath到targetPath的路径差异。 - 如果
basePath是/a/b/c,而targetPath是/a/b/d/e,则结果就是../d/e。
✅ 示例 1:兄弟路径(sibling paths)
java
Path p1 = Paths.get("joe");
Path p2 = Paths.get("sally");
Path fromJoeToSally = p1.relativize(p2);
Path fromSallyToJoe = p2.relativize(p1);
System.out.println(fromJoeToSally); // ../sally
System.out.println(fromSallyToJoe); // ../joe
📌 解释:
joe和sally是同一层级目录,想从joe到sally,需要先回到上一级(..),再进入sally。
✅ 示例 2:父子路径
java
Path p1 = Paths.get("home");
Path p3 = Paths.get("home/sally/bar");
Path fromHomeToBar = p1.relativize(p3);
Path fromBarToHome = p3.relativize(p1);
System.out.println(fromHomeToBar); // sally/bar
System.out.println(fromBarToHome); // ../..
📌 解释:
- 从
home到home/sally/bar,就是往下走两个目录。 - 从
home/sally/bar到home,则需要往上退两层。
❗ 注意事项
- 两个路径必须都是相对的或都是绝对的 ,否则会抛出
IllegalArgumentException。
java
// 错误示例:混合使用相对路径和绝对路径
Paths.get("/home").relativize(Paths.get("data/file.txt")); // ❌ 会抛异常
- 如果两个路径没有共同根(比如不同的盘符 C:\ vs D:\),无法计算相对路径。
💡 实际应用:构造目标路径
我们经常会将 relativize() 与 resolve() 搭配使用:
java
Path sourceDir = Paths.get("/home/joe");
Path targetFile = Paths.get("/home/joe/docs/report.txt");
// 获取相对于 sourceDir 的路径
Path relative = sourceDir.relativize(targetFile); // docs/report.txt
// 现在可以将这个路径 "移植" 到另一个目录下
Path backupDir = Paths.get("/mnt/backup");
Path backupFile = backupDir.resolve(relative); // /mnt/backup/docs/report.txt
📦 这在递归复制、迁移、备份路径结构时非常实用!
🧾 总结表
| 路径 A | 路径 B | A.relativize(B) |
|---|---|---|
joe |
sally |
../sally |
home |
home/sally/bar |
sally/bar |
home/sally/bar |
home |
../.. |
/a/b |
/a/c/d |
../c/d |
/data/log |
data/logs (相对) |
❌ 错误(混类型) |
📌 小技巧
- 想象你的路径是一棵树,
relativize()就是从一棵分支走向另一棵分支的最短路线。 - 可以用它结合
resolve()来完成路径的"重映射"操作。