大家在接触mapreduce时,对于一个文件要分片,在分片末尾会不会有一条记录被拆开,从而导致map端在输入的时候,会不会有一行记录是不完整的疑惑,其实这肯定是不可能,如果这样的问题没有解决,那在生产生活中肯定是经常遇到,所以hadoop源码中肯定有这方面的处理,今天就带大家看看mapreduce中的源码,我们这次看的是hadoop2.8版本的,其他版本差距不大。
首先肯定想到的是读取文本文件的类是TextInputFormat,其中比较重要的方法是createRecordReader方法
public RecordReader<LongWritable, Text> createRecordReader(InputSplit split, TaskAttemptContext context) {
String delimiter = context.getConfiguration().get("textinputformat.record.delimiter");
byte[] recordDelimiterBytes = null;
if(null != delimiter) {
recordDelimiterBytes = delimiter.getBytes(Charsets.UTF_8);
}
return new LineRecordReader(recordDelimiterBytes);
}
这里主要是从配置中读取了文本的记录之间的分隔符,如果不另外在设置别的分隔符,这里的recordDelimiterBytes就是空值,则默认CR和LF这些换行符为record的分隔符,将分隔符设成UTF-8的形式传入到LineRecordReader中去,意思是每次碰到一个分隔符,就为一条记录,然后我们再去LineRecordReader类中去看,我们去看nextKeyValue()方法,当其返回true时,就会调用getCurrentKey()和getCurrentValue()去获取key和value
public boolean nextKeyValue() throws IOException {
if(this.key == null) {
this.key = new LongWritable();
}
this.key.set(this.pos);
if(this.value == null) {
this.value = new Text();
}
int newSize = 0;
//getFilePosition()当前文件的偏移量,end表示split结束的位置
while(this.getFilePosition() <=