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) 收藏 举报