Site icon Experiences Unlimited

Getting to know about java.nio.file.Path – 2

In Part 1 of this, we looked at most of the APIs in the java.nio.file.Path class. In this article, we will look at the remaining APIs.

Using register()

This API allows us to register an implementation of java.nio.file.WatchService interface which will listen for events like directory creation, modification, and deletion. And it intimates the listeners by means of a java.nio.file.WatchKey. I would like to dedicate a different article for this API because it involves another new feature which was introduced in Java 7.

Using resolve()

This method deals with two Path instances. One instance on this the resolve() method is called and the other instance which is passed as an argument. The argument can be either a Path instance or a String representing the path.

This method resolves the other path against this path. The resolution is done as follows:

  1. If the other path is an absolute path, then it returns the other path. Because the other path can be reached by using the absolute path.
  2. If the other path is a relative path then the other path is appended to this path. For example:
    Path path = Paths.get("src", "main", "resources");
    Path other = Paths.get("blogsamples");
    
    assertThat(path.resolve(other)).isEqualTo(
            Paths.get("src", "main", "resources", "blogsamples"));

The different scenarios in which this method can be invoked is given in the test below:

@Test
public void testResolved() throws IOException {
    Path path = Paths.get("src", "main", "resources");
    Path other = Paths.get("blogsamples");

    assertThat(path.resolve(other)).isEqualTo(
            Paths.get("src", "main", "resources", "blogsamples"));

    other = Paths.get("/Users");
    assertThat(path.resolve(other)).isEqualTo(Paths.get("/Users"));

    path = Paths.get("/src", "main", "resource");
    assertThat(path.resolve("/Users")).isEqualTo(Paths.get("/Users"));
}

Using resolveSibling()

This method is similar to resolve() except that it considers this path’s parent to resolve the other path. Again there are different possibilities which I have captured in the test below:

@Test
public void testResolveSibling(){
    Path path = Paths.get("src", "main", "resources", "test1");
    Path other = Paths.get("test2");

    //both paths are not absolute
    assertThat(path.resolveSibling(other)).isEqualTo(
            Paths.get("src", "main", "resources", "test2"));

    //other path is absolute
    assertThat(path.resolveSibling("/test2")).isEqualTo(
        Paths.get("/test2"));

    //this path has no parent
    path = Paths.get("/");
    assertThat(path.resolveSibling("/test2")).isEqualTo(
        Paths.get("/test2"));

    //the other path is empty and this path has no parent
    assertThat(path.resolveSibling("")).isEqualTo(Paths.get(""));

    //the other path is empty and this path has parent
    path = Paths.get("src", "main", "resources", "test1");
    assertThat(path.resolveSibling("")).isEqualTo(
            Paths.get("src", "main", "resources"));
}

Using relativize()

This method returns a relative path that when resolved against this path returns the other path (i.e the path which is passed as a parameter).

I have tried to illustrate in the tests below the different possibilities while trying to create a relative path between two paths.

Path path = Paths.get("src", "main", "resources", "test1");
Path other = Paths.get("test2");

assertThat(path.relativize(other).toString())
    .isEqualTo("..\\..\\..\\..\\test2");

In the above case, both the paths are relative. It requires 4 hops backward from the src/main/resources/test1 to reach /test2. The same is obtained by applying the relativize method.

If one of the paths is absolute and the other is relative, then invoking relativize results in an IllegalArgumentException as shown below:

@Test(expected = IllegalArgumentException.class)
public void testRelativize_WithRelativeAndAbsolutePath(){
    Path path = Paths.get("/src", "main", "resources", "test1");
    Path other = Paths.get("src", "main", "resources");
    path.relativize(other);
}

If both the paths are absolute, then the output of relativize() is implementation dependent. The below test is written against JDK 8 on Windows platform:

@Test
public void testRelativize_WithAbsolutePaths(){
    Path path = Paths.get("/src", "main", "resources", "test1");
    Path other = Paths.get("/src", "main", "resources", "test1", "test2");
    assertThat(path.relativize(other).toString())
        .isEqualTo("test2");
}

Using startsWith()

This method checks if the path on which the startsWith() method has the same name elements in the beginning as that of the path passed as the argument. And the path passed as the argument has no extra name elements that are not present in this path.

For example: /a/b/c starts with /a/b , a/b/c/d starts with a/b/c

Let us look at the different possible cases while invoking the method:

@Test
public void testStartsWith(){
    //both paths are absolute
    Path path = Paths.get("/src", "main", "resources", "test1");
    Path other = Paths.get("/src", "main", "resources");
    assertThat(path.startsWith(other)).isTrue();

    /*
    both paths are absolute, where as the other 
    path has more name elements 
    */
    path = Paths.get("/src", "main", "resources", "test1");
    other = Paths.get("/src", "main", "resources", 
        "test1", "test2");
    assertThat(path.startsWith(other)).isFalse();

    //both paths are same
    path = Paths.get("/src", "main", "resources", "test1");
    other = Paths.get("/src", "main", "resources", "test1");
    assertThat(path.startsWith(other)).isTrue();

    //either of them is relative
    path = Paths.get("src", "main", "resources", "test1");
    other = Paths.get("/src", "main", "resources", "test1");
    assertThat(path.startsWith(other)).isFalse();

    //both of them are relative
    path = Paths.get("src", "main", "resources", "test1");
    other = Paths.get("src", "main", "resources");
    assertThat(path.startsWith(other)).isTrue();

}
Exit mobile version