【问题标题】:Hadoop get relative path from absolute path and base pathHadoop从绝对路径和基本路径获取相对路径
【发布时间】:2013-07-23 18:37:38
【问题描述】:

在给定绝对基本路径的情况下,我想从绝对路径中获取相对路径。是否有任何 Hadoop Java API 可以做到这一点?

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

例如,如果我有rel_path 和abs_base_path,我可以使用Path 类http://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/Path 中的重载构造函数之一来构建abs_path,但我找不到执行相反操作的API。

【问题讨论】:

  • 我想出的方法是将 abs_base_path 和 abs_path 都转换为 String do abs_path_str.replace(abs_base_path_str, StringUtils.EMPTY)。想不出更好的方法来做到这一点。

标签: java hadoop mapreduce


【解决方案1】:

这实际上是在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 创建一个新路径。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2021-08-15
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2011-08-11
      • 2010-09-21
      • 2023-03-22
      相关资源
      最近更新 更多