继承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中这一点仍 ...
随机推荐
- tomcat正常关闭,端口号占用解决 StandardServer.await: create[8005]:
cmd进入依次输入以下三个命令 1:netstat -ano | findstr "8005"2:tasklist | findstr "5632" 3:tas ...
- sqoop导出数据
export是HDFS里的文件导出到RDBMS的工具,不能从hive.hbase导出数据,且HDFS文件只能是文本格式.如果要把hive表数据导出到RDBMS,可以先把hive表通过查询写入到一个临时 ...
- jeecg权限设置案例
JEECG简单实例讲解权限控制 一.业务背景 某公司要实现一个日志系统,用来了解员工的工作量饱和情况. 二.需求 1.角色分为:员工.经理两种. 2.员工每天在日志系统中填报工作总结,然后经理进行点评 ...
- (转)老男孩:Linux企业运维人员最常用150个命令汇总
近来老男孩发现新手学习Linux记不住命令,不会分类.不会筛选重点,胡子眉毛一把抓当然记不住了. 特别整理Linux运维最常用150个命令和大家分享,大家学习命令不用在盲目了,根据分类,然后逐步学习! ...
- 明码(C++)
2.明码(结果填空) (满分7分) 注意事项:问题的描述在考生文件夹下对应题号的“题目.txt”中.相关的参考文件在同一目录中.请先阅读题目,不限解决问题的方式,只要求提交结果.必须通过浏览器提交答案 ...
- 比特币--私钥->公钥->钱包地址
脑钱包-字符串SHA256散列成256bit当做私钥-彩虹表 脑钱包是开源的程序-->用户输入字符串当做密码-->经过SHA256散列算法-->256长bit位 (即是私钥)--&g ...
- DEDE日期调用小插件
在日期文本框里面,点击的时候,下面出来一个和万年历一样的日期选择表,在dede里面,有一个现成的js小插件,直接调用就OK了... <input type="text" on ...
- Homemade Script Language: RED
Made by C, named after RED(RecovEr from SaDness) 欢迎批评 :)
- C#入门--字段与属性
C#入门--字段与属性 “字段”,它是包含在类或结构中的对象或值.字段使类和结构可以封装数据. 属性是这样的成员:它们提供灵活的机制来读取.编写或计算私有字段的值.可以像使用公共数据成员一样使用属性, ...
- CSS的相对定位和绝对定位(position)
什么是定位呢? 定位(position),故名思议,就是确定元素在页面中的位置. CSS的常用定位有两种,一种是相对定位,一种是绝对定位. 下面我们看例子 <html> <head& ...