MapReducer中獲取輸入檔案路徑
阿新 • • 發佈:2018-12-15
正常情況:
在社群版的hadoop版本0.19/0.20中,當使用普通的輸入的時候,比如:
job.setInputFormatClass(TextInputFormat.class);
在mapper執行的時候,可以用如下的方法得到對應的filesplit,也就能拿到對應的"輸入路徑"等資訊
FileSplit fileSplit = (FileSplit)(reporter.getInputSplit()); // 版本:0.19
FileSplit fileSplit = (FileSplit)(context.getInputSplit()); // 版本:0.20
String fileName = fileSplit.getPath().toUri().getPath();
遇到問題:
但是如果是使用:
MultipleInputs.addInputPath(job, new Path(path),
SequenceFileInputFormat.class, ProfileMapper.class);
在mapper中再使用上面的那種方式,就會報出一個型別轉換錯誤: java.lang.ClassCastException: org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit cannot be cast to org.apache.hadoop.mapreduce.lib.input.FileSplit
解決辦法及原理:
問題原因:
我們需要的filesplit實際上就是TaggedInputSplit中的成員變數inputSplit 然而TaggedInputSplit這個類在社群版中並不是public的,所以我們並不能直接直接拿到對應的資訊了;不知道後續的社群版是怎麼做的?可能已經修改了吧
解決辦法:
通過反射來獲得TaggedInputSplit中的inputSplit:
import java.io.IOException;
import java.lang.reflect.Method;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Mapper.Context;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
public class MapperUtils {
/**
* 獲得輸入檔案路徑
* */
public static String getFilePath(Context context) throws IOException {
InputSplit split = context.getInputSplit();
Class<? extends InputSplit> splitClass = split.getClass();
FileSplit fileSplit = null;
if (splitClass.equals(FileSplit.class)) {
fileSplit = (FileSplit) split;
} else if(splitClass.getName().equals("org.apache.hadoop.mapreduce.lib.input.TaggedInputSplit")){
try{
Method getInputSplitMethod = splitClass.getDeclaredMethod("getInputSplit");
//設定訪問許可權 true:不需要訪問許可權檢測直接使用 false:需要訪問許可權檢測
getInputSplitMethod.setAccessible(true);
fileSplit = (FileSplit) getInputSplitMethod.invoke(split);
} catch (Exception e) {
throw new IOException(e);
}
}
return fileSplit.getPath().toUri().getPath();
}
}
此時,通過: String filePath = MapperUtils.getFilePath(context); 即可獲取輸入檔案路徑