Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: how to normalize paths with nio Path?

Tags:

java

nio

One of the really nice things about java.io.File is that it can normalize paths to a predictable format.

new File("/", inputPath).getPath() always returns a string with relative paths normalized out, and always starting and ending with predictable path separators.

Is there a way to do this with the new nio Path or Paths classes?

(Note also that I am dealing with abstract paths for other systems, this has nothing to do with any local filesystem)

Further examples of behavior I want:

 - "/foo" -> "/foo"
 - "//foo/" -> "/foo"
 - "foo/" -> "/foo"
 - "foo/bar" -> "/foo/bar"
 - "foo/bar/../baz" -> "/foo/baz"
 - "foo//bar" -> "/foo/bar"
like image 892
TREE Avatar asked Jan 20 '15 19:01

TREE


People also ask

What is path normalization Java?

The normalize() method of java. nio. file. Path used to return a path from current path in which all redundant name elements are eliminated. The precise definition of this method is implementation dependent and it derives a path that does not contain redundant name elements.

What is path normalization?

What is path normalization? Normalizing a path involves modifying the string that identifies a path or file so that it conforms to a valid path on the target operating system. Normalization typically involves: Canonicalizing component and directory separators. Applying the current directory to a relative path.

How do you compare paths in Java?

Two file paths can be compared lexicographically in Java using the method java. io. File. compareTo().

How do you create an absolute path in Java?

The method java. io. File. getAbsolutePath() is used to obtain the absolute path of a file in the form of a string.


1 Answers

This code works:

public final class Foo
{
    private static final List<String> INPUTS = Arrays.asList(
        "/foo", "//foo", "foo/", "foo/bar", "foo/bar/../baz", "foo//bar"
    );

    public static void main(final String... args)
    {
        Path path;

        for (final String input: INPUTS) {
            path = Paths.get("/", input).normalize();
            System.out.printf("%s -> %s\n", input, path);
        }
    }
}

Output:

/foo -> /foo
//foo -> /foo
foo/ -> /foo
foo/bar -> /foo/bar
foo/bar/../baz -> /foo/baz
foo//bar -> /foo/bar

NOTE however that this is NOT portable. It won't work on Windows machines...

If you want a portable solution you can use memoryfilesystem, open a Unix filesystem and use that:

try (
    final FileSystem fs = MemoryFileSystem.newLinux().build();
) {
    // path operations here
}
like image 196
fge Avatar answered Nov 15 '22 13:11

fge