InputFormat

一 InputFormat主要作用:

InputFormat抽象类仅有两个抽象方法:
List<InputSplit> getSplits(), 获取由输入文件计算出输入分片(InputSplit),解决数据或文件分割成片问题。
RecordReader<K,V> createRecordReader(),创建RecordReader,从InputSplit中读取数据,解决读取分片中数据问题。
(1)验证job的输入规范
(2)对输入的文件进行切分,形成多个InputSplit文件,每一个InputSplit对应着一个map任务
(3)创建RecordReader,从InputSplit分片中读取数据供map使用

二 FileInputFormat: 处理文件


FileInputFormat默认情况下,如果一个文件小于blockSize,那么这个文件就是一个InputSplits, 如果大于blockSize,则是先按照文件大小/blockSize,如果有剩余单独成为一个InputSplit。

(1)Text:

文件按照行划分,key就是这一行在文件中的偏移量,value就是这一行文本


(2)FiexedLength

读取输入文件的固定长度的记录,这种文件不该是文本文件,二进制文件比较多


(3)KeyValue

用于读取普通文本文件,文件按照行分割,按分隔符把一行数据切割,前面是key,后面是value组成,key 和 value的分隔符若没有指定,那么整行为key,value为空

(4)NLine

是可以将N行数据划分为一个Split,作为MapTask输入

(5)CombineTextInputFormat

把多个小文件合并成一个切片处理,提高处理效率

(6)自定义


三 DBInputFormat: 处理数据库


四 CombineFileInputFormat


CombineFileInputFormat通过合并多个小文件成为一个分片,分片过程也考虑同一节点,同一机架的数据本地性,让每一个Mapper任务可以处理更多的数据

五:自定义

(1)FileRecordReader

package com.atguigu.InputFormat;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;

public class wholeFileDriver {
    public static void main(String[] args) throws Exception {
        Job job = Job.getInstance(new Configuration());

        job.setJarByClass(wholeFileDriver.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(BytesWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(BytesWritable.class);

        job.setInputFormatClass(wholeFileInputFormat.class);
        job.setOutputFormatClass(SequenceFileOutputFormat.class);

        FileInputFormat.setInputPaths(job,new Path("/test"));
        FileOutputFormat.setOutputPath(job,new Path("/test2"));

        boolean b = job.waitForCompletion(true);
        System.exit(b?0:1);
    }


}

(2)FileInputFormat

package com.atguigu.InputFormat;


import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.IOUtils;
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 java.io.IOException;


//自定义RecordReader,处理一个文件,返回key-value
public class wholeFileRecordReader extends RecordReader<Text, BytesWritable> {

    private boolean notread = true; //文件没读过
    private Text key =new Text();
    private BytesWritable value = new BytesWritable();
    private FSDataInputStream inputStream;
    private FileSplit fs;

    //初始化方法:框架会在开始的时候调用一次
    public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {

        //转换切片类型到文件切片
        fs = (FileSplit) split;
        //通过切片获取路径
        Path path = fs.getPath();
        //通过路径获取文件系统
        FileSystem fileSystem = path.getFileSystem(context.getConfiguration());
        //开流
        inputStream = fileSystem.open(path);


    }

    //读取下一组kv值,如果读到了返回true
    public boolean nextKeyValue() throws IOException, InterruptedException {
        if(notread){
            //读key
            key.set(fs.getPath().toString());
            //读value
            byte[] buf = new byte[(int) fs.getLength()];
            inputStream.read(buf);
            value.set(buf,0,buf.length);



            notread = false;
            return true;
        }else{
            return false;
        }

    }

    //获取当前读到的key
    public Text getCurrentKey() throws IOException, InterruptedException {
        return key;
    }

    //获取当前读到的value
    public BytesWritable getCurrentValue() throws IOException, InterruptedException {
        return value;
    }

    //读取进度
    public float getProgress() throws IOException, InterruptedException {
        return notread?0:1;
    }

    //关闭资源
    public void close() throws IOException {
        IOUtils.closeStream(inputStream);

    }
}

(3)FileDriver

package com.atguigu.InputFormat;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;

public class wholeFileDriver {
    public static void main(String[] args) throws Exception {
        Job job = Job.getInstance(new Configuration());

        job.setJarByClass(wholeFileDriver.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(BytesWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(BytesWritable.class);

        job.setInputFormatClass(wholeFileInputFormat.class);
        job.setOutputFormatClass(SequenceFileOutputFormat.class);

        FileInputFormat.setInputPaths(job,new Path("/test"));
        FileOutputFormat.setOutputPath(job,new Path("/test2"));

        boolean b = job.waitForCompletion(true);
        System.exit(b?0:1);
    }


}

 

posted on 2020-11-13 18:29  happygril3  阅读(180)  评论(0)    收藏  举报

导航