Java 查找和替换路径

huangapple go评论65阅读模式
英文:

Java find and replace path

问题

在不将其转换为字符串的情况下,是否可以在 Path 对象中进行 findreplace 操作?

例如,这是一个简单的代码片段:

import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

  public static void main(String[] args)  {

    final Path wholePath = Paths.get("/usr/animals/data/donkey/folder1/folder2/data.txt");
    final Path find = Paths.get("/usr/animals/data/donkey");
    final Path replace = Paths.get("/usr/animals/data/sym4");

    Path expected = Paths.get("/usr/animals/data/sym4/folder1/folder2/data.txt"); // 如何获得这个路径?

    Path path = wholePath.resolve(find.relativize(wholePath).toString().replace(find.toString(), replace.toString()));

    System.out.println(expected.equals(path));
  }
}

使用 .toString() 方法似乎是一种非便携的方式,更好的做法是使用 .resolve() 或类似的方法吗?

有什么建议吗?

英文:

Is it possible to find and replace in a Path object without converting it to a String?

For example here is a simple code snippet,

import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

  public static void main(String[] args)  {

    final Path wholePath = Paths.get("/usr/animals/data/donkey/folder1/folder2/data.txt");
    final Path find = Paths.get("/usr/animals/data/donkey");
    final Path replace = Paths.get("/usr/animals/data/sym4");

    Path expected = Paths.get("/usr/animals/data/sym4/folder1/folder2/data.txt"); // how to get this?

    Path path = Paths.get(wholePath.toString().replace(find.toString(), replace.toString()));

    System.out.println(expected.equals(path));
  }
}
     

Using a .toString() method seems to be a non-portable way and instead it's better to use the .resolve() or similar method?

Any suggestions?

答案1

得分: 2

是的,您可以使用Files API 来实现,但这不是一步完成的。

final Path wholePath = Paths.get("/usr/animals/data/donkey/folder1/folder2/data.txt");
final Path find = Paths.get("/usr/animals/data/donkey");
final Path replace = Paths.get("/usr/animals/data/sym4");

// 这里是两行关键代码
Path relativized = find.relativize(wholePath);
Path path = replace.resolve(relativized);

Path expected = Paths.get("/usr/animals/data/sym4/folder1/folder2/data.txt");

System.out.println(expected.equals(path));

基本上,这段代码将wholePath拆分为“将要被替换的部分”和“剩余的部分”,存储在relativized中。然后,它使用新的root来解析relativized路径。

英文:

Yes, you can do it using Files API, but it will just not be in single step.

    final Path wholePath = Paths.get("/usr/animals/data/donkey/folder1/folder2/data.txt");
    final Path find = Paths.get("/usr/animals/data/donkey");
    final Path replace = Paths.get("/usr/animals/data/sym4");

    //here comes 2 lines of magic
    Path relativized = find.relativize(wholePath);
    Path path = replace.resolve(relativized);
    

    Path expected = Paths.get("/usr/animals/data/sym4/folder1/folder2/data.txt");

    System.out.println(expected.equals(path));

This basicly splits wholePath to "what will be replaced" and "what is left" as relativized. Then it resolves relativized path using new root

答案2

得分: 2

在你的示例中,实际上并没有进行查找和替换操作,而是在重新设定路径基准,即改变路径的前缀。

为了实现这一点,你首先要将输入,即wholePath(绝对路径),转换为相对路径,相对于旧的根路径find,这样你就得到了folder1/folder2/data.txt,然后你将其与新的根路径replace解析合并。

你可以通过调用relativize(Path other)resolve(Path other) 来实现:

Path input = Paths.get("/usr/animals/data/donkey/folder1/folder2/data.txt");
Path oldRoot = Paths.get("/usr/animals/data/donkey");
Path newRoot = Paths.get("/usr/animals/data/sym4");

Path relativePath = oldRoot.relativize(input);
Path result = newRoot.resolve(relativePath); // /usr/animals/data/sym4/folder1/folder2/data.txt
英文:

In your example, you are not actually finding and replacing, you are re-basing the path, i.e. you are changing the prefix of the path.

To do that, you first convert the input, i.e. wholePath, which is an absolute path, to a relative path, relative to the old root path, i.e. find, so you get folder1/folder2/data.txt, then you resolve that against the new root path, i.e. replace.

You do that by calling relativize(Path other) and resolve(Path other), like this:

Path input = Paths.get("/usr/animals/data/donkey/folder1/folder2/data.txt");
Path oldRoot = Paths.get("/usr/animals/data/donkey");
Path newRoot = Paths.get("/usr/animals/data/sym4");

Path relativePath = oldRoot.relativize(input);
Path result = newRoot.resolve(relativePath); // /usr/animals/data/sym4/folder1/folder2/data.txt

huangapple
  • 本文由 发表于 2020年9月15日 14:34:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63896366.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定