InputFormat是MapReduce编程模型包括5个可编程组件之一,其余4个是Mapper、Partitioner、Reducer和OutputFormat。

新版Hadoop InputFormat是一个抽象类,之前的InputFormat是一个接口。

InputFormat类有两个抽象方法。

方法getSplits将输入数据切分成InputSlits,InputSplits的个数即为map tasks的个数,InputSplits的大小默认为块大小,即64M
public abstract List<InputSplit> getSplits(JobContext context) throws IOException, InterruptedException;
方法createRecordReader将每个InputSplit解析成RecordReader, 再依次将RecordReader解析成<K,V>对
public abstract RecordReader<K,V> createRecordReader(InputSplit split,TaskAttemptContext context) throws IOException,InterruptedException;

也就是说InputFormat完成以下工作:

 InputFile --> InputSplits --> RecordReader --> <K,V>
FileInputFormat类的getSplits方法实现了文件切分。
 
InputFormat的子类,其中TextInputFormat便是最常用的,它的<K,V>就代表<行偏移,该行内容>

自己实现的一个RecordReader

package tokenize.inputformat;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.CombineFileSplit; public class MyRecordReader extends RecordReader<Text, Text> { private CombineFileSplit combineFileSplit; // 当前处理的分片
private int totalLength; // 分片包含的文件数量
private int currentIndex; // 当前处理的文件索引
private float currentProgress = 0; // 当前的进度
private Text currentKey = new Text(); // 当前的Key
private Text currentValue = new Text(); // 当前的Value
private Configuration conf; // 任务信息
private boolean processed; // 记录当前文件是否已经读取 public MyRecordReader(CombineFileSplit combineFileSplit,
TaskAttemptContext context, Integer index) throws IOException {
super();
this.currentIndex = index;
this.combineFileSplit = combineFileSplit;
conf = context.getConfiguration();
totalLength = combineFileSplit.getPaths().length;
processed = false;
} @Override
public void initialize(InputSplit split, TaskAttemptContext context)
throws IOException, InterruptedException {
} @Override
public Text getCurrentKey() throws IOException, InterruptedException {
return currentKey;
} @Override
public Text getCurrentValue() throws IOException, InterruptedException {
return currentValue;
} @Override
public float getProgress() throws IOException {
if (currentIndex >= 0 && currentIndex < totalLength) {
currentProgress = (float) currentIndex / totalLength;
return currentProgress;
}
return currentProgress;
} @Override
public void close() throws IOException {
} @Override
public boolean nextKeyValue() throws IOException {
if (!processed) { // 如果文件未处理则读取文件并设置key-value
// set key
Path file = combineFileSplit.getPath(currentIndex);
currentKey.set(file.getParent().getName()); // category's name
// set value
FSDataInputStream in = null;
byte[] contents = new byte[(int)combineFileSplit.getLength(currentIndex)];
try {
FileSystem fs = file.getFileSystem(conf);
in = fs.open(file);
in.readFully(contents);
currentValue.set(contents);
} catch (Exception e) {
} finally {
in.close();
}
processed = true;
return true;
}
return false; //如果文件已经处理,必须返回false
} }
package tokenize.inputformat;

import java.io.IOException;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.CombineFileRecordReader;
import org.apache.hadoop.mapreduce.lib.input.CombineFileSplit; public class MyInputFormat extends CombineFileInputFormat<Text, Text> {
/**
* make sure file will not be splitted
*/
@Override
protected boolean isSplitable(JobContext context, Path file) {
return false;
} /**
* specify record reader
*/
@Override
public RecordReader<Text, Text> createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException {
CombineFileRecordReader<Text, Text> recordReader = new CombineFileRecordReader<Text, Text>(
(CombineFileSplit)split, context, MyRecordReader.class);
return recordReader;
} }

Hadoop InputFormat详解的更多相关文章

  1. Hadoop Streaming详解

    一: Hadoop Streaming详解 1.Streaming的作用 Hadoop Streaming框架,最大的好处是,让任何语言编写的map, reduce程序能够在hadoop集群上运行:m ...

  2. Python API 操作Hadoop hdfs详解

    1:安装 由于是windows环境(linux其实也一样),只要有pip或者setup_install安装起来都是很方便的 >pip install hdfs 2:Client——创建集群连接 ...

  3. Hadoop Pipeline详解[摘抄]

    最近使用公司内部的一个框架写map  reduce发现没有封装hadoop streaming这些东西,查了下pipeline相关的东西 Hadoop Pipeline详解 20. Aug / had ...

  4. hadoop框架详解

    Hadoop框架详解 Hadoop项目主要包括以下四个模块 ◆ Hadoop Common: 为其他Hadoop模块提供基础设施 ◆ Hadoop HDFS: 一个高可靠.高吞吐量的分布式文件系统 ◆ ...

  5. Hadoop基本命令详解

    调用文件系统(FS)Shell命令应使用bin/hadoop fs <args>的形式.所有的的FS shell命令使用URI路径作为参数.URI路径详解点击这里. 1.cat 说明:将路 ...

  6. hadoop shell 详解

    概述  所有的hadoop命令均由bin/hadoop脚本引发.不指定参数运行hadoop脚本会打印所有命令的描述.  用法: hadoop [--config confdir] [COMMAND] ...

  7. Hadoop实战之二~ hadoop作业调度详解(1)

    对Hadoop的最感兴趣的地方,也就在于Hadoop的作业调度了,在正式介绍如何搭建Hadoop之前,深入理解一下Hadoop的作业调度很有必要.我们不一定能用得上Hadoop,但是如果理通顺Hado ...

  8. mapreduce: InputFormat详解 -- RecordReader篇

    InputFormat是MapReduce中一个很常用的概念,它在程序的运行中到底起到了什么作用呢? InputFormat其实是一个接口,包含了两个方法: public interface Inpu ...

  9. Hadoop配置文件详解

    1       获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知 ...

随机推荐

  1. Poj 2136 Vertical Histogram(打印垂直直方图)

    一.Description Write a program to read four lines of upper case (i.e., all CAPITAL LETTERS) text inpu ...

  2. 用Azure CLI批量上传文件

    在Windows环境下,我们可以使用AzCopy批量上传文件.其效率和传输速率都是非常快的. 在Linux或MacOS环境下,可以使用Azure的CLI实现批量文件的上传. 下面的脚本可以实现此功能. ...

  3. PG peered实验

    标签(空格分隔): ceph,ceph实验,pg 1. 创建一个文件,并把该文件作为对象放到集群中: [root@node1 ~]# echo "this is test! " & ...

  4. qtp重定义数组大小

    a dim arr1() ) a  dim arr() ReDim arr(a) arr arr ) arr For each i in arr     print arr(i) Next

  5. springMVC绑定json参数之二(2.2.3)

    二.springmvc 接收不同格式的json字符串 4).格式四:json传递复杂对象(对象中有属性,还有List) 复杂对象: package testVO; import java.util.L ...

  6. [51nod1106]质数检测

    解题关键: 根据质数的定义,在判断一个数n是否是质数时,我们只要用1至n-1去除n,看看能否整除即可.但我们有更好的办法.先找一个数m,使m的平方大于n,再用<=m的质数去除n(n即为被除数), ...

  7. 面试题17:打印1到最大的n位数

    // 面试题17:打印1到最大的n位数 // 题目:输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则 // 打印出1.2.3一直到最大的3位数即999. 解题思路: 首先是一个大陷阱,n ...

  8. JavaScript -- 常用的数组及字符串方法

    数组 var arr= new Array(); arr.push(); //在数组尾部添加一个元素,返回新的长度 *原数组发生变化 arr.pop(); //删除最后一个元素,返回的是被删除的元素 ...

  9. Hadoop localhost ssh 免密码登陆

    配置本地ssh免密码登陆,遇到很奇怪的问题,原来在公司电脑上,是按照 http://blog.csdn.net/hackerwin7/article/details/28109073 这里说的配置的, ...

  10. css 实现三级联动菜单

    昨天因为项目中想要把二级联动菜单改成三级联动菜单,所以我就单独写了一个tab导航栏,用纯css的方式实现的三级联动.一开始我想着可以用js实现,但是js的hover事件和mouseenter,mous ...