Hadoop从绝对路径和基本路径获取相对路径

时间:2013-07-23 18:37:39

标签: java hadoop mapreduce

我希望从绝对路径获得相对路径,给定绝对基本路径。是否有任何Hadoop Java API可以做到这一点?

例如,如果我的绝对HDFS路径是abs_path = hdfs://name-node/level1/level2/level3而我的绝对基本路径是abs_base_path = hdfs://name-node/level1,我想从abs_path中提取相对路径,{{1} }}。我熟悉使用路径构造函数来组合两个路径。

例如,如果我有rel_path = level2/level3rel_path,我可以使用Path类abs_base_path中的一个重载构造函数来构建http://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/Path,但我找不到用于反向的API。

2 个答案:

答案 0 :(得分:4)

这实际上是在FileOutputCommitter的源代码中完成的。相关功能是

   /**
   * 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;
    }
  }

我们的想法是为基本目录创建一个URI,然后为这个新的,相对化的URI创建一个新的路径。

希望有所帮助。

答案 1 :(得分:0)

如何在使用getParent()递归时构建String,直到当前路径等于基本路径?这是一个可以做你想要的帮助函数。 (我还没有测试过,但这个想法可能会有所帮助)

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();
}