2013-07-23 304 views
1

我想從絕對路徑獲取絕對基路徑的相對路徑。有沒有這樣的Hadoop Java API?Hadoop從絕對路徑和基本路徑獲取相對路徑

例如,如果我的絕對HDFS路徑是abs_path = hdfs://name-node/level1/level2/level3和我的絕對基本路徑是abs_base_path = hdfs://name-node/level1,我想從abs_path提取的相對路徑,這將是rel_path = level2/level3。我熟悉使用路徑構造函數來組合兩條路徑。

舉例來說,如果我有rel_pathabs_base_path,我可以使用重載的構造函數中的一個Path類http://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/Path打造abs_path,但我無法找到一個API做相反。

+0

我想出的辦法是將abs_base_path和abs_path轉換爲字符串做abs_path_str.replace(abs_base_path_str,StringUtils.EMPTY)。想不到更好的方法來做到這一點。 –

回答

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

這在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創建一個新的路徑。

希望有所幫助。