在我的输入目录中,我有一个要处理的文件列表以及一个元数据文件。在输出reducer端,我想索引到这个文件,只是将额外的元数据添加到输出中。我怎样才能获得输入目录?
在旧的API中,可以这样做:
context.getConfiguration().get("map.input.dir")
新的API允许映射器执行此操作:
(FileSplit)context.getInputSplit()).getPath()
但是Reducer上下文没有这个功能。此外,对于简单的任务来说,进行连接似乎有些过分。
答案 0 :(得分:1)
Reducer
在Mappers
的输出上运行,因此Context
中没有关于输入文件的信息。现在要识别reduce
中的输入目录,您只需要使用您共享的代码在map
中标记outValue,此处加入无关紧要。例如:
<强>地图
String tag = (FileSplit)context.getInputSplit()).getPath()
.getParent().getName().toString();
context.write(outKey, new Text(tag + "_" + value.toString));
如果您对fileName本身感兴趣(确实应该是这种情况),请删除getParent()
来电。
<强> REDUCE 强>
String metaFileName = "meta.dat";
for(Text value : values){
String[] tagVal = value.toString().split("_",2);
if(strVal[0].equals(metaFileName){
// process the meta file here // strVal[1] contains the actual value
} else { // process data files }
}
这应该可以解决您的问题。这里有一个建议,你可以利用MultiOutputs
api从reducer写入不同类型的文件。否则,在作业结束后,将很难识别metaFile(它将分布在多个输出文件中)。
答案 1 :(得分:0)
MapReduce作业的输入由FileInputFormat.addInputPath()
方法指定。正如方法名称所暗示的那样,可以多次调用addInputPath()
方法来指定其他文件和/或目录作为MapReduce作业的输入。因此,可能有多个路径作为单个MapReduce作业的输入。
Mapper任务对单个拆分进行操作。因此,Mapper能够检索正在处理的特定拆分的路径是有意义的。
然而,Reducers通常在多个映射器的输出上运行,其输入分裂可能(可能)具有不同的路径。因此,在Reducer中没有InputSplit的概念,这就是为什么你无法获得它的路径。