3

This is a seemingly simple problem but I am having trouble doing it in a clean manner. I have a file path as follows:

/this/is/an/absolute/path/to/the/location/of/my/file

What I need is to extract /of/my/file from the above given path since that is my relative path.

The way I am thinking of doing it is as follows:

String absolutePath = "/this/is/an/absolute/path/to/the/location/of/my/file";
String[] tokenizedPaths = absolutePath.split("/");
int strLength = tokenizedPaths.length;
String myRelativePathStructure = (new StringBuffer()).append(tokenizedPaths[strLength-3]).append("/").append(tokenizedPaths[strLength-2]).append("/").append(tokenizedPaths[strLength-1]).toString();

This will probably serve my immediate needs but can somebody suggest a better way of extracting sub-paths from a provided path in java?

Thanks

sc_ray
  • 7,803
  • 11
  • 63
  • 100
  • You have to either know what the root path looks like or what the "child" path looks like. – Kiril Mar 22 '12 at 16:48

2 Answers2

11

Use the URI class:

URI base = URI.create("/this/is/an/absolute/path/to/the/location");
URI absolute =URI.create("/this/is/an/absolute/path/to/the/location/of/my/file");
URI relative = base.relativize(absolute);

This will result in of/my/file.

McDowell
  • 107,573
  • 31
  • 204
  • 267
  • Thanks. I was wondering if there was a way to have more control over what to relativize. Would it be possible to somehow grab /the/location/of/my/file in a similar elegant manner? – sc_ray Mar 22 '12 at 18:59
  • @sc_ray - yes, change your base URI. – jtahlborn Mar 22 '12 at 19:34
  • @sc_ray Have a look at `File`'s [getParentFile](http://docs.oracle.com/javase/7/docs/api/java/io/File.html#getParentFile%28%29) method. `File` contains methods for converting to/from `URI` instances. Java 7 users _might_ be able to use the `Path` type in the [java.nio.file](http://docs.oracle.com/javase/7/docs/api/java/nio/file/package-summary.html) package - I haven't looked at it in any depth. – McDowell Mar 23 '12 at 09:02
1

With pure string operations and assuming you know the base path and assuming you only want relative paths below the base path and never prepend a "../" series:

String basePath = "/this/is/an/absolute/path/to/the/location/";
String absolutePath = "/this/is/an/absolute/path/to/the/location/of/my/file";
if (absolutePath.startsWith(basePath)) {
    relativePath = absolutePath.substring(basePath.length());
}

There are surely better ways to do this with classes that are aware of path logic, such as File or URI, though. :)

user1252434
  • 2,083
  • 1
  • 15
  • 21