输入文件1:
factoryname addressed
Beijing Red Star 1
Shenzhen Thunder 3
Guangzhou Honda 2
Beijing Rising 1
Guangzhou Development Bank 2
Tencent 3
Back of Beijing 1
输入文件2:
addressID addressname
1 Beijing
2 Guangzhou
3 Shenzhen
4 Xian
要想得到的输出文件:
factoryname addressname
Beijing Red Star Beijing
Beijing Rising Beijing
Back of Beijing Beijing
Guangzhou Honda Guangzhou
Guangzhou Development Bank Guangzhou
Shenzhen Thunder Shenzhen
Tencent Shenzhen
自己编写的运行正确的map/reduce源码:
package bin;
import java.io.IOException;
import java.util.Iterator;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class MTJoin {
// 对于两个不同的输入文件的处理,前面的文件都是相同格式的,这里的两个文件格式不同,实现的是两个文件的自然连接
public static class MTJoinMap extends Mapper<Object, Text, Text, Text>{
//map做的事是将不同文件中的数据进行处理分发;继承了mapper之后就要实现其中的map方法
public void map(Object key,Text value,Context context) {
//每次执行map函数,就会读取文件中的一行数据给value,要对value进行处理;
String line=new String(value.toString());
String MapKey=new String();
String MapValue=new String();
if (line.contains("factoryname")||line.contains("addressed")||line.contains("addressID")||line.contains("addressname")) {
return;
}
int len=line.length();
String flag=new String();//记录属于左表还是属于右表;
//每个map任务按行读取文件,将读取的一行数据交给map函数执行处理,即,每一行数据调用一次map函数,
//所以这里的一个tokenizer的容器,包含的数据,在这里只有两个,当读取下一行数据时,就会再次调用一次MTJoinMap的map函数
//------------------------------由此,这里的i的意义就很明显了。
//当每一行数据读进来初始时,i的值均为0,所以当文件为第一个文件,即第二位为ID时,flag="1",当文件为第一个文件时,即第一位为ID,则,i=0,--> flag="2"
String[] record=line.split(" ");
if (len==0) {
return;
}else {
if (line.charAt(0) > '0' && line.charAt(0) < '9') {
flag="2";
MapKey=String.valueOf(line.charAt(0));
for (int i = 1; i < record.length; i++) {
MapValue =MapValue.concat(record[i]).concat(" ");
}
}else if (line.charAt(len-1) > '0' && line.charAt(len-1) < '9') {
flag="1";
MapKey=String.valueOf(line.charAt(len-1));
for (int i = 0; i < record.length-1; i++) {
if (record[i].equals(" ")) {
continue;
}
MapValue =MapValue.concat(record[i]).concat(" ");
}
}
try {
context.write(new Text(MapKey), new Text(flag+"+"+MapValue));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static int time=0;
public static class MTJoinReduce extends Reducer<Text, Text, Text, Text>{
public void reduce(Text key,Iterable<Text> values,Context context) {
if (time==0) {
try {
context.write(new Text("factoryname"), new Text("addressname"));
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
time++;
}//输出表头信息factory name address name
String[] factoryname=new String[10];
int factoryNum=0;
String addressname=new String();
Iterator<Text> iterator=values.iterator();
while (iterator.hasNext()) {
String record= iterator.next().toString();
int len=record.length();//以下这三句不加会报错: Exception closing file /user/xinxin/output/MutiTableJoin_out
if (len==0) {//一定要判定迭代器里面的字符串为空的情况
continue;
}
char flag=record.charAt(0);
if (flag=='1' && record.substring(2).length()!=0) {
factoryname[factoryNum]=record.substring(2);
factoryNum++;
}else if (flag=='2' && record.substring(2).length()!=0)
addressname = record.substring(2);
}
if (factoryNum!=0 && addressname.length()!=0) {
for (int i = 0; i < factoryNum; i++) {
try {
context.write(new Text(factoryname[i]), new Text(addressname));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration configuration=new Configuration();
String[] otherArgs = new GenericOptionsParser(configuration,args).getRemainingArgs();
if (otherArgs.length !=2) {
System.err.println("Usage: MTJoin <in> <out>");
System.exit(2);
}
Job job =new Job(configuration, "tracert MTJoin");
job.setJarByClass(MTJoin.class);
job.setMapperClass(MTJoinMap.class);
job.setReducerClass(MTJoinReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true)? 0 : 1);
}
}
作者原创,如果转载请注明出处,谢谢
---------------------------------------------------------欣