继承FileInputFormat类来理解 FileInputFormat类
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.hadoop.fs.BlockLocation;
- import org.apache.hadoop.fs.FileStatus;
- import org.apache.hadoop.fs.FileSystem;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.fs.PathFilter;
- import org.apache.hadoop.io.LongWritable;
- import org.apache.hadoop.io.Text;
- import org.apache.hadoop.mapreduce.InputFormat;
- 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.FileInputFormat;
- import org.apache.hadoop.mapreduce.lib.input.InvalidInputException;
- import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
- import org.apache.hadoop.mapreduce.lib.input.LineRecordReader;
- //import org.apache.hadoop.mapreduce.lib.input.FileInputFormat.MultiPathFilter;
- import org.apache.hadoop.mapreduce.security.TokenCache;
- import com.google.common.base.Charsets;
- public class MyFileinput extends FileInputFormat<LongWritable, Text> {
- private static final PathFilter hiddenFileFilter = new PathFilter() {
- public boolean accept(Path p) {
- String name = p.getName();
- return ((!(name.startsWith("_"))) && (!(name.startsWith("."))));
- }
- };
- // 遍历文件列表, 过滤掉_ .开头的文件(可以自定义过滤)
- protected List<FileStatus> listStatus(JobContext job) throws IOException {
- System.out.println("*********************");
- List result = new ArrayList();
- Path[] dirs = getInputPaths(job);
- System.out.println("dirs" + dirs);
- System.out.println("dirs length = " + dirs.length);
- for(Path p: dirs){
- System.out.println("Path loop " + p);
- }
- if (dirs.length == 0) {
- throw new IOException("No input paths specified in job");
- }
- TokenCache.obtainTokensForNamenodes(job.getCredentials(), dirs,
- job.getConfiguration());
- List errors = new ArrayList();
- List filters = new ArrayList();
- filters.add(hiddenFileFilter);
- PathFilter jobFilter = getInputPathFilter(job);
- if (jobFilter != null) {
- filters.add(jobFilter);
- }
- // 过滤函数,可以拓展
- PathFilter inputFilter = new MultiPathFilter(filters);
- for (int i = 0; i < dirs.length; ++i) {
- Path p = dirs[i];
- FileSystem fs = p.getFileSystem(job.getConfiguration());
- FileStatus[] matches = fs.globStatus(p, inputFilter);
- System.out.println("matches=" + matches);
- for(FileStatus match: matches){
- System.out.println("loop matches" + match.getPath());
- }
- if (matches == null)
- errors.add(new IOException("Input path does not exist: " + p));
- else if (matches.length == 0)
- errors.add(new IOException("Input Pattern " + p
- + " matches 0 files"));
- else {
- for (FileStatus globStat : matches) {
- System.out.println("globStat " + globStat);
- if (globStat.isDirectory())
- for (FileStatus stat : fs.listStatus(
- globStat.getPath(), inputFilter)) {
- result.add(stat);
- }
- else {
- result.add(globStat);
- }
- }
- }
- }
- if (!(errors.isEmpty())) {
- throw new InvalidInputException(errors);
- }
- // LOG.info("Total input paths to process : " + result.size());
- return result;
- }
- // 计算分片大小,返回一个分片列表
- public List<InputSplit> getSplits(JobContext job) throws IOException {
- long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));
- long maxSize = getMaxSplitSize(job);
- System.out.print("minSize " + minSize);
- System.out.print("maxSize " + maxSize);
- List splits = new ArrayList();
- // 获取输入目录下的文件列表(过滤文件)
- List<FileStatus> files = listStatus(job);
- for (FileStatus file : files) {
- Path path = file.getPath();
- long length = file.getLen();
- System.out.println("path: " + path+ " file len = " + length);
- if (length != 0L) {
- // 通过路径找到块列表
- FileSystem fs = path.getFileSystem(job.getConfiguration());
- BlockLocation[] blkLocations = fs.getFileBlockLocations(file,
- 0L, length);
- if (isSplitable(job, path)) {
- long blockSize = file.getBlockSize();
- System.out.println("blockSize:" + blockSize);
- long splitSize = computeSplitSize(blockSize, minSize,
- maxSize);
- System.out.println("splitSize :" + splitSize);
- long bytesRemaining = length;
- System.out.println("bytesRemaining :" + bytesRemaining);
- System.out.println(bytesRemaining / splitSize);
- // 定义为1.1D, 为避免一个分片过小, 也需要启动一个MAP来运行
- // 最后剩余的文件大小只要不超过分片大小的1.1倍都会放入一个分片
- while (bytesRemaining / splitSize > 1.1D) {
- int blkIndex = getBlockIndex(blkLocations, length
- - bytesRemaining);
- System.out.println("blkIndex :" + blkIndex);
- // 添加到分片分片列表
- splits.add(makeSplit(path, length - bytesRemaining,
- splitSize, blkLocations[blkIndex].getHosts()));
- bytesRemaining -= splitSize;
- }
- // 文件尾
- if (bytesRemaining != 0L) {
- Long remain = length - bytesRemaining;
- System.out.println("文件尾大小" + bytesRemaining);
- int blkIndex = getBlockIndex(blkLocations, length
- - bytesRemaining);
- splits.add(makeSplit(path, length - bytesRemaining,
- bytesRemaining,
- blkLocations[blkIndex].getHosts()));
- }
- } else {
- splits.add(makeSplit(path, 0L, length,
- blkLocations[0].getHosts()));
- }
- } else {
- // 测试文件大小为0, 也会启动一个map
- splits.add(makeSplit(path, 0L, length, new String[0]));
- }
- }
- job.getConfiguration().setLong(
- "mapreduce.input.fileinputformat.numinputfiles", files.size());
- // LOG.debug("Total # of splits: " + splits.size());
- return splits;
- }
- private static class MultiPathFilter implements PathFilter {
- private List<PathFilter> filters;
- public MultiPathFilter(List<PathFilter> filters) {
- this.filters = filters;
- }
- public boolean accept(Path path) {
- for (PathFilter filter : this.filters) {
- if (!(filter.accept(path))) {
- return false;
- }
- }
- return true;
- }
- }
- // 文件内容读取, 默认按行读取
- @Override
- public RecordReader<LongWritable, Text> createRecordReader(
- InputSplit split, TaskAttemptContext context) {
- String delimiter = context.getConfiguration().get(
- "textinputformat.record.delimiter");
- System.out.println("delimiter ==" + delimiter);
- // 默认为空
- byte[] recordDelimiterBytes = null;
- if (null != delimiter)
- recordDelimiterBytes = delimiter.getBytes(Charsets.UTF_8);
- return new LineRecordReader(recordDelimiterBytes);
- }
- }
主要功能是计算分片和按照分片给MAP任务读取内容
public abstract class InputFormat<K, V> {
public abstract List<InputSplit> getSplits(JobContext paramJobContext)
throws IOException, InterruptedException;
public abstract RecordReader<K, V> createRecordReader(
InputSplit paramInputSplit,
TaskAttemptContext paramTaskAttemptContext) throws IOException,
InterruptedException;
}
从顶层的派生类提供的接口差不多也能看出来。
最简单的Informat实现, 然后我们只要实现RecordReader就可以了
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.io.LongWritable;
- 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.FileInputFormat;
- import org.apache.hadoop.mapreduce.lib.input.LineRecordReader;
- import com.google.common.base.Charsets;
- public class MySimpleInformat<V> extends FileInputFormat<LongWritable, V>
- {
- protected boolean isSplitable(JobContext context, Path filename) {
- // 是否需要分片
- return false;
- }
- @Override
- public RecordReader<LongWritable, V> createRecordReader(
- InputSplit split, TaskAttemptContext context) {
- String delimiter = context.getConfiguration().get(
- "textinputformat.record.delimiter");
- System.out.println("delimiter ==" + delimiter);
- // 默认为空
- byte[] recordDelimiterBytes = null;
- if (null != delimiter)
- recordDelimiterBytes = delimiter.getBytes(Charsets.UTF_8);
- return (RecordReader<LongWritable, V>) new LineRecordReader(recordDelimiterBytes);
- }
- }
继承FileInputFormat类来理解 FileInputFormat类的更多相关文章
- java 面向对象(三十八):反射(二) Class类的理解与获取Class的实例
1.Class类的理解 1.类的加载过程:程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾).接着我们使用java.exe命令对某个字节码文件进行解释运行.相当于将某个 ...
- Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限
一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...
- 对C++类的继承和派生的理解
C++中的继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承类似,例如儿子继承父亲的财产. 1.继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程. ...
- Python之美[从菜鸟到高手]--深刻理解原类(metaclass)
本来想自己写这篇文章的,可当我读了这篇文章http://blog.jobbole.com/21351/,我打消了这个念头,因为肯定写的没有人家的好,说的通俗易懂,面面俱到.就厚着面皮修改下格式,测试下 ...
- Java基础12:深入理解Class类和Object类
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- 对Java中properties类的理解
转载于:https://www.cnblogs.com/bakari/p/3562244.html 一.Java Properties类 Java中有个比较重要的类Properties(Java.ut ...
- 对类的理解(c++)
介绍目录: 1.类成员 1.1 成员函数 1.2 构造函数 1.2.1 对构造函数的理解 1.2.2成员初始化列表 1.2.3必须使用成员初始化列表的几种情况 1.2.4对于拷贝构造函数的参数是一个引 ...
- [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式
使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...
- 深刻理解Python中的元类(metaclass)以及元类实现单例模式
在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Python中这一点仍 ...
随机推荐
- jmeter使用总结
1.1 什么是 JMeter Apache JMeter 是 Apache 组织开发的基于 Java 的压力测试工具.用于对软件做压力测试,它最初被设计用于 Web 应用测试,但后来扩展到其他测试领域 ...
- selenium-webdriver(python) (十四) -- webdriver原理(转)
之前看乙醇视频中提到,selenium 的ruby 实现有一个小后门,在代码中加上$DEBUG=1 ,再运行脚本的过程中,就可以看到客户端请求的信息与服务器端返回的数据:觉得这个功能很强大,可以帮助理 ...
- if else 选择机构 _多重if选择机构_if选择结构嵌套(综合练习题——code)
import java.util.*; class If01{ public static void main(String[ ]args){ //练习1:假如张三参加Java考试,判断如果在95分以 ...
- PlayMaker Int的两个数进行比较 Int Compare
Integer 1 和 Integer 2 进行比较,Integer 1 和 Integer 2 相等的时候 执行 ChangeToGreen; Integer 1 比 Integer 2 大的时 ...
- 对象池2(方法功能)Pools
对象池Pools(主要调用方法功能) namespace kernal { public class Pools : MonoBehaviour { [HideInInspector] public ...
- 自定义Qt组件-通讯模块(P1)
通讯模块Communicator 通讯模块是整个项目设计中位于最底层的模块,用于处理与串口或网络等设备的通讯,所有设备的通讯通过CommManager类完成,上层软件设计时需要根据comm模块(主要是 ...
- 高精度运算——java
java大法 java的框架. import java.io.*; import java.util.*; import java.math.*; public class Main{ public ...
- 随机练习:C#实现维吉尼亚加密与解密(解密前提为已知密匙)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- JavaSE之Java基础(1)
1.为什么重写equals还要重写hashcode 首先equals与hashcode间的关系是这样的: 1.如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相 ...
- SSM环境下配置log4j输出sql和异常到控制台和本地日志文件中
1.引入日志依赖包 <!--解决Spring使用slf4j输出日志与log4j冲突的问题--> <dependency> <groupId>org.slf4j< ...