1

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
  • Strings are actually pretty portable, however to avoid them you can use .getParent().getParent().getParent().getParent().resolve(newDirName).resolve(...) Commented Sep 15, 2020 at 6:45

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.