Reputation: 1177
I want to get the relative path from an absolute path, given the absolute base path. Is there any Hadoop Java API that does this?
For example, if my absolute HDFS path is abs_path = hdfs://name-node/level1/level2/level3
and my absolute base path is abs_base_path = hdfs://name-node/level1
, I would like to extract the relative path from abs_path
, which would be rel_path = level2/level3
. I am familiar with using the path constructor to combine two paths.
For example, if I have the rel_path
and abs_base_path
, I can use one of the overloaded constructors in the Path class http://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/Path
to build abs_path
but I cannot find an API to do the reverse.
Upvotes: 2
Views: 5736
Reputation: 3978
This is actually done in FileOutputCommitter
's source code. The relevant function is
/**
* Find the final name of a given output file, given the job output directory
* and the work directory.
* @param jobOutputDir the job's output directory
* @param taskOutput the specific task output file
* @param taskOutputPath the job's work directory
* @return the final path for the specific output file
* @throws IOException
*/
private Path getFinalPath(Path jobOutputDir, Path taskOutput,
Path taskOutputPath) throws IOException {
URI taskOutputUri = taskOutput.toUri();
URI relativePath = taskOutputPath.toUri().relativize(taskOutputUri);
if (taskOutputUri == relativePath) {
throw new IOException("Can not get the relative path: base = " +
taskOutputPath + " child = " + taskOutput);
}
if (relativePath.getPath().length() > 0) {
return new Path(jobOutputDir, relativePath.getPath());
} else {
return jobOutputDir;
}
}
The idea is to create a URI for the base directory and then create a new Path for this new, relativized URI.
Hope that helps.
Upvotes: 6
Reputation: 1911
How about building a String while recursing with getParent() until the current path is equal to the base path? Here is a helper function that might do what you want. (I haven't tested it yet, but the idea might help)
private static String absolutePathToRelativeString(final Path path, final Path base) {
final StringBuilder builder = new StringBuilder(path.toString().length());
Path curPath = new Path(path);
while (curPath != null && curPath.depth() != 0 && !curPath.equals(base)) {
if (!curPath.equals(path)) {
builder.append('/');
}
builder.insert(0, curPath.getName());
curPath = curPath.getParent();
}
return builder.toString();
}
Upvotes: 0