InputFormat接口(package org.apache.hadoop.mapreduce包中)里包括两个方法:getSplits()和createRecordReader(),这两个方法分别用来定义输入分片和读取分片的方法。 

 1 public abstract class InputFormat<K, V> {
 2 
 3   public abstract 
 4     List<InputSplit> getSplits(JobContext context
 5                                ) throws IOException, InterruptedException;
 6   
 7 
 8   public abstract 
 9     RecordReader<K,V> createRecordReader(InputSplit split,
10                                          TaskAttemptContext context
11                                         ) throws IOException, 
12                                                  InterruptedException;
13 }

  getSplits()负责将文件切分成多个分片(InputSplit),但InputSplit并没有实际切分文件,而只是说明了如何切分数据,也就是说,InputSplit只是逻辑上的切分。createRecordReader()则创建了RecordReader,用来从InputSplit读取记录。

  

  再看InputSplit类,它包括了getLength()和getLocation()两个方法。getLength()方法用来获取InputSplit的大小,getLocation()则用来获取InputSplit的位置。

1 public abstract class InputSplit {
2 
3   public abstract long getLength() throws IOException, InterruptedException;
4 
5   public abstract 
6     String[] getLocations() throws IOException, InterruptedException;
7 }

  每个InputSplit对应一个map任务。作为map的输入,在逻辑上提供了这个map任务所要处理的key-value对。

 

  InputSplit只是定义了如何切分文件,但并没有定义如何访问它,这个工作由RecordReader来完成。RecordReader的实例是由InputFormat定义的。例如,在InputFormat的默认子类TextInputFormat中,提供了LineRecordReader。 

 1 package org.apache.hadoop.mapreduce.lib.input;
 2 
 3 public class TextInputFormat extends FileInputFormat<LongWritable, Text> {
 4 
 5   @Override
 6   public RecordReader<LongWritable, Text> 
 7     createRecordReader(InputSplit split,
 8                        TaskAttemptContext context) {
 9     return new LineRecordReader();
10   }

 

  LineRecordReader会把文件的每一行作为一个单独的记录,并以行偏移为键值。这也就解释了WordCount例子中,行偏移为key值,每一行的内容作为value的原因。

  本文基于hadoop1.2.1

  如有错误,还请指正

  参考文章:《Hadoop应用开发技术详解》  刘刚

  转载请注明出处:http://www.cnblogs.com/gwgyk/p/3997734.html 

posted on 2014-09-28 09:43  有无之中  阅读(4247)  评论(0编辑  收藏  举报