MapReduce默认的InputFormat是TextInputFormat,且key是偏移量,value是文本,自定义InputFormat需要实现FileInputFormat,并重写createRecorder方法,如果需要还可以重写isSplitable()来设置是否切片,重写了createRecordReader还需要自定义RecordReader,InputFormat规定了key,value是什么,而RecordReader则是具体的读取逻辑,下面的例子是合并小文件,最终输出的k是文件路径,v是文件二进制字节

1.InputFormat

 /**
* 自定义InputFormat规定读取文件的k,v
* @author tele
*
*/
public class MyInputFormat extends FileInputFormat<NullWritable,BytesWritable>{
/**
* 设置不切片,把小文件作为一个整体
*/
@Override
protected boolean isSplitable(JobContext context, Path filename) {
return false;
} @Override
public RecordReader<NullWritable,BytesWritable> createRecordReader(InputSplit split, TaskAttemptContext context)
throws IOException, InterruptedException {
MyRecordReader recordReader = new MyRecordReader();
recordReader.initialize(split, context);
return recordReader;
}
}

2.RecordReader

 /**
* recordreader用于读取文件内容,输出文件内容即可,文件路径信息保存在split中
* @author tele
*
*/
public class MyRecordReader extends RecordReader<NullWritable,BytesWritable> {
FileSplit split;
BytesWritable value = new BytesWritable();
boolean flag = false;
Configuration conf;
int count = ; /**
* 初始化
*/
@Override
public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
this.split = (FileSplit) split;
conf = context.getConfiguration(); conf = context.getConfiguration();
} /**
* 业务逻辑处理,这个方法用来判断是否还有文件内容需要读取,会进入两次,第一次读取内容存入value中,返回true,第二次调用返回false
* 只要返回true,就会调用getCurrentKey().getCurrentValue()把内容返回给map
*
*/
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
count++;
if(!flag) {
//获取fs
FileSystem fs = FileSystem.get(conf);
//开启流
Path path = this.split.getPath();
FSDataInputStream fsDataInputStream = fs.open(path);
long length = this.split.getLength();
byte[] buf = new byte[(int) length]; //读取
IOUtils.readFully(fsDataInputStream, buf, ,buf.length);
value.set(buf, , buf.length); //关闭流
IOUtils.closeStream(fsDataInputStream);
flag = true;
}else {
flag = false;
}
return flag;
} @Override
public NullWritable getCurrentKey() throws IOException, InterruptedException {
return NullWritable.get();
} @Override
public BytesWritable getCurrentValue() throws IOException, InterruptedException {
return value;
} @Override
public float getProgress() throws IOException, InterruptedException {
return flag?:;
} @Override
public void close() throws IOException { }
}

3.Mapper

 /**
* 把结果输出到SequenceFileOutPutFormat中,输出的key是文件路径,value为文件内容
* @author tele
*
*/
public class InputformatMapper extends Mapper<NullWritable, BytesWritable, Text,BytesWritable/*Text*/> {
Text k = new Text(); @Override
protected void map(NullWritable key, BytesWritable value,
Mapper<NullWritable, BytesWritable, Text, BytesWritable/*Text*/>.Context context)
throws IOException, InterruptedException {
FileSplit split = (FileSplit) context.getInputSplit();
Path path = split.getPath(); k.set(path.toString()); /* String result = new String(value.getBytes(),0,value.getLength());
context.write(k,new Text(result));*/ context.write(k, value);
}
}

4.Driver(由于输出的是字节,需要指定OutputFormat为SequenceFileOutputFormat)

 /**
* 驱动
* @author tele
*
*/
public class InputformatDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//1.获得job实例
Configuration conf = new Configuration();
Job job = Job.getInstance(conf); //2.关联class
job.setJarByClass(InputformatDriver.class);
job.setMapperClass(InputformatMapper.class); //4.设置format
job.setInputFormatClass(MyInputFormat.class);
//使用SequenceFileOutputFormat作为输出格式
job.setOutputFormatClass(SequenceFileOutputFormat.class); //5.数据类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(BytesWritable.class); // job.setOutputValueClass(Text.class); //6.设置输入与输出路径
FileInputFormat.setInputPaths(job,new Path(args[]));
FileOutputFormat.setOutputPath(job,new Path(args[])); //7.提交
boolean result = job.waitForCompletion(true);
System.exit(result?:);
}
}

MapReduce自定义InputFormat,RecordReader的更多相关文章

  1. 【Hadoop离线基础总结】MapReduce自定义InputFormat和OutputFormat案例

    MapReduce自定义InputFormat和OutputFormat案例 自定义InputFormat 合并小文件 需求 无论hdfs还是mapreduce,存放小文件会占用元数据信息,白白浪费内 ...

  2. MapReduce自定义InputFormat和OutputFormat

    一.自定义InputFormat 需求:将多个小文件合并为SequenceFile(存储了多个小文件) 存储格式:文件路径+文件的内容 c:/a.txt I love Beijing c:/b.txt ...

  3. MapReduce之自定义InputFormat

    在企业开发中,Hadoop框架自带的InputFormat类型不能满足所有应用场景,需要自定义InputFormat来解决实际问题. 自定义InputFormat步骤如下: (1)自定义一个类继承Fi ...

  4. MapReduce 重要组件——Recordreader组件 [转]

    (1)以怎样的方式从分片中读取一条记录,每读取一条记录都会调用RecordReader类: (2)系统默认的RecordReader是LineRecordReader,如TextInputFormat ...

  5. MapReduce 重要组件——Recordreader组件

    (1)以怎样的方式从分片中读取一条记录,每读取一条记录都会调用RecordReader类: (2)系统默认的RecordReader是LineRecordReader,如TextInputFormat ...

  6. 自定义InputFormat和OutputFormat案例

    一.自定义InputFormat InputFormat是输入流,在前面的例子中使用的是文件输入输出流FileInputFormat和FileOutputFormat,而FileInputFormat ...

  7. Hadoop案例(六)小文件处理(自定义InputFormat)

    小文件处理(自定义InputFormat) 1.需求分析 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案.将多个小文件合并 ...

  8. 自定义inputformat和outputformat

    1. 自定义inputFormat 1.1 需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案 1.2 分析 小文件的优 ...

  9. Hadoop_28_MapReduce_自定义 inputFormat

    1. 自定义inputFormat 1.1.需求: 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件,此时就需要有相应解决方案; 1.2.分析: 小文件的优化 ...

随机推荐

  1. 详解javascript的深拷贝与浅拷贝

    1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...

  2. Codeforces Round 363 Div. 1 (A,B,C,D,E,F)

    Codeforces Round 363 Div. 1 题目链接:## 点击打开链接 A. Vacations (1s, 256MB) 题目大意:给定连续 \(n\) 天,每天为如下四种状态之一: 不 ...

  3. 通过Rman catalog 创建及管理Oracle数据库备份

    基本环境信息target DB (需备份数据库) 192.168.199.67 ORACLE_SID=zgw HOSTNAME=Oracle11 catlog DB (备份管理数据库) 192.168 ...

  4. vue指令概览

    原文 简书原文:https://www.jianshu.com/p/5fd47b7422fd 大纲 1.什么是vue指令 2.向指令中传入参数 3.指令中带入修饰符 4.指令的缩写 5.常见的vue指 ...

  5. 基于mpvue的小程序项目搭建的步骤一

    未标题-1.png mpvue 是美团开源的一套语法与vue.js一致的.快速开发小程序的前端框架,按官网说可以达到小程序与H5界面使用一套代码.使用此框架,开发者将得到完整的 Vue.js 开发体验 ...

  6. 【例题 6-4 UVA - 11988】Broken Keyboard (a.k.a. Beiju Text)

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 会链表的插入操作的话.这个就不难了. 放置两个哨兵节点. 然后模拟插入一个节点的过程就好. 实时修改光标就好->即下一个插入的 ...

  7. Netty原理和使用

    性能主题 Netty原理和使用 Netty是一个高性能 事件驱动的异步的非堵塞的IO(NIO)框架,用于建立TCP等底层的连接,基于Netty可以建立高性能的Http服务器.支持HTTP. WebSo ...

  8. AIR 初步 Javascript学习之cookie操作

    //设置cookie的名称,值,过期时间         function setCookie(cookieName,cookieValue,cookieExpire) {             v ...

  9. 【例题3-6 UVA - 1584】Circular Sequence

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 不用真的把每一位都取出来. 用一个后缀的思想. 把原串复制一遍接在后面,然后把每个字符串 都当成一个长度为n的后缀就好了. 比较每个 ...

  10. Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)

    Crazy Bobo Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Tota ...