Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the longest Path common to two Paths in Java

Tags:

java

file

If I have two Paths, how can I find the longest common Path of the two?

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

Path common(Path pathA, Path pathB) {
    ...
}
...
common(Paths.get("/a/b/c/d/e"), Paths.get("/a/b/c/g/h"))

Expected output:

Paths.get("/a/b/c")
like image 453
Alex Spurling Avatar asked Mar 04 '23 13:03

Alex Spurling


2 Answers

Path path1 = Paths.get("/a/b/c/d/e");
Path path2 = Paths.get("/a/b/c/g/h");

You can relativize the paths to one another:

Path relativePath = path1.relativize(path2).normalize();
// result: ../../g/h

and then go to the parent until the path ends in ..

while(relativePath != null && !relativePath.endsWith("..")) {
    relativePath = relativePath.getParent();
}
// result: ../.. (but may also be null)

the result can be applied back to any of the two paths:

Path result = path1.resolve(relativePath).normalize()
// result: /a/b/c
like image 55
Felk Avatar answered Mar 13 '23 06:03

Felk


Try this simple idea

    Path a = Paths.get("a/b/c/d/e");
    Path b = Paths.get("a/b/c/g/h");

    // Normalize
    a = a.normalize();
    b = b.normalize();

    // Create common root
    Path common = null;
    if (a.isAbsolute() && b.isAbsolute() && a.getRoot().equals(b.getRoot())) {
            common = a.getRoot();
    }
    else if (!a.isAbsolute() && !b.isAbsolute()) {
            common = Paths.get("");
    }

    // Iterate from root until names differ
    if (common != null) {
            int n = Math.min(a.getNameCount(), b.getNameCount());
            for (int i=0; i<n; i++) {
                    if (a.getName(i).equals(b.getName(i))) {
                            common = common.resolve(a.getName(i));
                    }
                    else {
                            break;
                    }
            }
    }

    // Show
    System.out.println(common);
like image 39
mnesarco Avatar answered Mar 13 '23 07:03

mnesarco