Hadoop代码測试环境:Hadoop2.4

应用:在对数据须要进行一定条件的过滤和简单处理的时候能够使用自己定义输入文件格式类。

Hadoop内置的输入文件格式类有:

1)FileInputFormat<K,V>这个是主要的父类,我们自己定义就直接使用它作为父类;

2)TextInputFormat<LongWritable,Text>这个是默认的数据格式类,我们一般编程,假设没有特别指定的话,一般都使用的是这个;key代表当前行数据距离文件開始的距离,value代码当前行字符串;

3)SequenceFileInputFormat<K,V>这个是序列文件输入格式,使用序列文件能够提高效率,可是不利于查看结果,建议在过程中使用序列文件,最后展示能够使用可视化输出;

4)KeyValueTextInputFormat<Text,Text>这个是读取以Tab(也即是\t)分隔的数据,每行数据假设以\t分隔,那么使用这个读入,就能够自己主动把\t前面的当做key,后面的当做value;

5)CombineFileInputFormat<K,V>合并大量小数据是使用;

6)MultipleInputs,多种输入,能够为每一个输入指定逻辑处理的Mapper;

原理:

InputFormat接口有两个重要的函数:

1)getInputSplits,用于确定输入分片,当我们继承FileInputFormat时,就能够忽略此函数,而使用FileInputFormat的此函数就可以;

2)createRecordReader ,针对数据怎样读取的类,定义输入文件格式,事实上也就是定义此类;

在每一个map函数中,最開始调用的都是nextKeyValue()函数,这个函数就是在RecordReader中定义的(我们自己定义RecordReader就是使用不同的实现而已),所以这里会调用我们指定的RecordReader中的nextKeyValue函数。这个函数就会处理或者说是初始化key和value,然后返回true,告知已经处理好了。接着就会调用getCurrentKey 和getCurrentValue获取当前的key和value值。最后,返回map,继续运行map逻辑。

自己定义输入文件格式类:

package fz.inputformat;

import java.io.IOException;

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.FileInputFormat;
/**
* 自己定义输入文件读取类
*
* @author fansy
*
*/
public class CustomInputFormat extends FileInputFormat<Text, Text> { @Override
public RecordReader<Text, Text> createRecordReader(InputSplit split,
TaskAttemptContext context) throws IOException,
InterruptedException {
// TODO Auto-generated method stub
return new CustomReader();
}
}

这里看到假设继承了FileInputFormat 后,就不须要关心getInputSplits了,而仅仅须要定义RecordReader就可以。

自己定义RecordReader

package fz.inputformat;

//import java.io.BufferedReader;
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.FileSplit;
import org.apache.hadoop.util.LineReader; public class CustomReader extends RecordReader<Text ,Text>{
// private BufferedReader in;
private LineReader lr ;
private Text key = new Text();
private Text value = new Text();
private long start ;
private long end;
private long currentPos;
private Text line = new Text();
@Override
public void initialize(InputSplit inputSplit, TaskAttemptContext cxt)
throws IOException, InterruptedException {
FileSplit split =(FileSplit) inputSplit;
Configuration conf = cxt.getConfiguration();
Path path = split.getPath();
FileSystem fs = path.getFileSystem(conf);
FSDataInputStream is = fs.open(path);
lr = new LineReader(is,conf); // 处理起始点和终止点
start =split.getStart();
end = start + split.getLength();
is.seek(start);
if(start!=0){
start += lr.readLine(new Text(),0,
(int)Math.min(Integer.MAX_VALUE, end-start));
}
currentPos = start;
} // 针对每行数据进行处理
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
if(currentPos > end){
return false;
}
currentPos += lr.readLine(line);
if(line.getLength()==0){
return false;
}
if(line.toString().startsWith("ignore")){
currentPos += lr.readLine(line);
} String [] words = line.toString().split(",");
// 异常处理
if(words.length<2){
System.err.println("line:"+line.toString()+".");
return false;
}
key.set(words[0]);
value.set(words[1]);
return true; } @Override
public Text getCurrentKey() throws IOException, InterruptedException {
return key;
} @Override
public Text getCurrentValue() throws IOException, InterruptedException {
return value;
} @Override
public float getProgress() throws IOException, InterruptedException {
if (start == end) {
return 0.0f;
} else {
return Math.min(1.0f, (currentPos - start) / (float) (end - start));
}
} @Override
public void close() throws IOException {
// TODO Auto-generated method stub
lr.close();
} }

这里主要是两个函数,initial和nextKeyValue。

initial主要用于初始化,包含打开和读取文件,定义读取的进度等;

nextKeyValue则是针对每行数据(因为这里使用的是LineReader,所以每次读取的是一行,这里定义不同的读取方式,能够读取不同的内容),产生相应的key和value对,假设没有报错,则返回true。这里能够看到设置了一条规则,假设输入数据是以ignore開始的话就忽略,同一时候每行仅仅取得逗号前后的数据分别作为key和value。

实战:

输入数据:

ignore,2
a,3
ignore,4
c,1
c,2,3,2
4,3,2
ignore,34,2

定义主类,主类的Mapper是默认的Mapper,没有reducer。

package fz.inputformat;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; public class FileInputFormatDriver extends Configured implements Tool{ /**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ToolRunner.run(new Configuration(), new FileInputFormatDriver(),args);
} @Override
public int run(String[] arg0) throws Exception {
if(arg0.length!=2){
System.err.println("Usage:\nfz.inputformat.FileInputFormatDriver <in> <out>");
return -1;
}
Configuration conf = getConf(); Path in = new Path(arg0[0]);
Path out= new Path(arg0[1]);
out.getFileSystem(conf).delete(out, true); Job job = Job.getInstance(conf,"fileintputformat test job");
job.setJarByClass(getClass()); job.setInputFormatClass(CustomInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class); job.setMapperClass(Mapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
// job.setOutputKeyClass(LongWritable.class);
// job.setOutputValueClass(VectorWritable.class);
job.setNumReduceTasks(0);
// System.out.println(job.getConfiguration().get("mapreduce.job.reduces"));
// System.out.println(conf.get("mapreduce.job.reduces"));
FileInputFormat.setInputPaths(job, in);
FileOutputFormat.setOutputPath(job, out); return job.waitForCompletion(true)?0:-1;
} }

查看输出:

这里能够看到,ignore的数据已经被忽略掉了,同一时候每行仅仅输出了逗号前后的数据而已。

同一时候须要注意到:

这里有一行数据读入的是空字符串,这个临时还没找到原因。

总结:自己定义输入数据格式能够针对不同的数据做些过滤,进行一些简单的逻辑处理,有点相似map的功能,可是假设仅仅是这点功能的话,那全然能够使用map来代替了。事实上输入数据格式还有其它的功能,比方合并大量的小数据,以提高效率,这个在下篇再说。

分享,成长,快乐

转载请注明blog地址:http://blog.csdn.net/fansy1990

hadoop编程小技巧(5)---自己定义输入文件格式类InputFormat的更多相关文章

  1. hadoop编程小技巧(5)---自定义输入文件格式类InputFormat

    Hadoop代码测试环境:Hadoop2.4 应用:在对数据需要进行一定条件的过滤和简单处理的时候可以使用自定义输入文件格式类. Hadoop内置的输入文件格式类有: 1)FileInputForma ...

  2. hadoop编程小技巧(7)---自己定义输出文件格式以及输出到不同文件夹

    代码測试环境:Hadoop2.4 应用场景:当须要定制输出数据格式时能够採用此技巧,包含定制输出数据的展现形式.输出路径.输出文件名称称等. Hadoop内置的输出文件格式有: 1)FileOutpu ...

  3. hadoop编程小技巧(1)---map端聚合

    測试hadoop版本号:2.4  Map端聚合的应用场景:当我们仅仅关心全部数据中的部分数据时,而且数据能够放入内存中. 使用的优点:能够大大减小网络数据的传输量,提高效率: 一般编程思路:在Mapp ...

  4. Java编程小技巧(1)——方法传回两个对象

    原文地址:Java编程小技巧(1)--方法传回两个对象 | Stars-One的杂货小窝 题目是个伪命题,由Java语法我们都知道,方法要么返回一个对象,要么就不返回 当有这样的情况,我们需要返回两个 ...

  5. Shellcode编程小技巧

    工作需要,需要注入其他程序监控一些东西,检测到的数据通过WM_COPY 消息发送给显示窗体.(大体是这样的还没定稿) ##1 选择一个框架 ## tombkeeper/Shellcode_Templa ...

  6. 学会这些 pycharm 编程小技巧,编程效率提升 10 倍

    PyCharm 是一款非常强大的编写 python 代码的工具.掌握一些小技巧能成倍的提升写代码的效率,本篇介绍几个经常使用的小技巧. 一.分屏展示 当你想同时看到多个文件的时候: 1.右击标签页: ...

  7. 积累的VC编程小技巧之工具条和状态条

    1.工具条和状态条中控件的添加: 方法⑴.只能在ToolBar里创建控件:首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上 ...

  8. 干货分享:小技巧大用处之Bean管理类工厂多种实现方式

    前言:最近几个月很忙,都没有时间写文章了,今天周末刚好忙完下班相对早点(20:00下班)就在家把之前想总结的知识点写出来,于是就有了这篇文章.虽无很高深的技术,但小技巧有大用处. 有时我们经常需要将实 ...

  9. 积累的VC编程小技巧之编辑框

    1.如何让对话框中的编辑框接收对话框的消息 ////////////////////////////////////////////////// 如何让对话框中的CEdit控件类接收对话框的消息/// ...

随机推荐

  1. win7已安装Mysql 开机自启动

    1.下载并安装MySql,我用MySQL_5.6.24_winx64_XiaZaiBa,解压缩到磁盘或更低.我在这里安装D菜,D:\install\MySQL\MySQL Server 5.6. 2. ...

  2. cocospods 卡在 Analyzing dependencies

    參考链接:http://www.cocoachina.com/bbs/read.php? tid=193398 关于pod stetup的详解在这里.对于初次使用CocoaPods的同学,即使你不使用 ...

  3. Linux经常使用的命令(十) - nl

    nl命令在linux系统中用来计算文件里行号. nl 能够将输出的文件内容自己主动的加上行号.其默认的结果与 cat -n 有点不太一样. nl 能够将行号做比較多的显示设计,包含位数与是否自己主动补 ...

  4. [原创].NET 分布式架构开发实战之二 草稿设计

    原文:[原创].NET 分布式架构开发实战之二 草稿设计 .NET 分布式架构开发实战之二 草稿设计 前言:本篇之所以称为草稿设计,是因为设计的都是在纸上完成的.反映了一个思考的过程. 本篇的议题如下 ...

  5. HDU 1677 Nested Dolls

    过了之后感觉曾经真的做过这样的类型的题. 之前一直非常疑惑二级排序的优先级问题,如今发现二级排序真的没有绝对的优先级. 对于此题,若按W排序,则有1到i件物品的W均小于等于第i+1件物品(设为A)的W ...

  6. Windows Server 2012启用Windows功能NetFx3时出错解决方法

    作者:冰点阳光 | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址:http://baohua.me/operating-system/windows-server-2012- ...

  7. 16.怎样自学Struts2之Struts2异常处理[视频]

    16.怎样自学Struts2之Struts2异常处理[视频] 之前写了一篇"打算做一个视频教程探讨怎样自学计算机相关的技术",优酷上传不了,仅仅好传到百度云上: http://pa ...

  8. hadoop-HBase-observer的一个样例

    hbase(main):021:0> describe 'users' DESCRIPTION                                                   ...

  9. struts2和struts1认识

    1.Struts 2基本流程 Struts 2框架本身可以大致分3部分:核心控制器FilterDispatcher.业务总监Action与用户实现企业业务逻辑组件. 核心控制器FilterDispat ...

  10. sgu128snack

    按我的理解大概说下题意: 有非常多个点,最多一万个,告诉你它们的坐标.如今须要构造一条闭合线.这个闭合线满足下面六点: 1必须是闭合的. 2必须用到全部的点. 3构造的线段之间若成角,则必须是90度. ...