源码
根据网上的实例,自己稍作修改,把文件读入输出地址,写在系统文件中,通过读文件控制。
import java.io.*;
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 WordCount {
/**
*
* @param args
* @throws IOException
* @throws ClassNotFoundException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
// TODO Auto-generated method stub
Configuration conf = new Configuration();// 取得系统的参数
// if (args.length != 2) { // 判断一下命令行输入路径/输出路径是否齐全,即是否为两个参数
// System.err.println("Usage: wordcount <in> <out>");
// System.exit(2); // 若非两个参数,即退出
// }
Job job = new Job(conf, "My Word Count"); // 此程序的执行,在hadoop看来是一个Job,故进行初始化job操作
/* 读取文件,文件中写了本次要处理的.txt地址和输出地址,用分好隔开 */
FileSystem fs = FileSystem.get(conf);
FSDataInputStream fin = fs.open(new Path("/user/zq/text.txt"));
BufferedReader in = null;
String line, inpath, outpath;
inpath = outpath = null;
try {
in = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
if ((line = in.readLine()) != null) {
String[] str = line.split(";");
inpath = str[0];
outpath = str[1];
}
} finally {
if (in != null)
in.close();
}
if (fs.exists(new Path(outpath))) {
fs.delete(new Path(outpath), true);
}
job.setJarByClass(WordCount.class); // 可以认为成,此程序要执行MyWordCount.class这个字节码文件
job.setMapperClass(TokenizerMapper.class); // 在这个job中,我用TokenizerMapper这个类的map函数
job.setReducerClass(IntSumReducer.class); // 在这个job中,我用IntSumReducer这个类的reduce函数
job.setOutputKeyClass(Text.class); // 在reduce的输出时,key的输出类型为Text
job.setOutputValueClass(IntWritable.class);// 在reduce的输出时,value的输出类型为IntWritable
FileInputFormat.addInputPath(job, new Path(inpath)); // 初始化要计算word的文件的路径
FileOutputFormat.setOutputPath(job, new Path(outpath)); // 初始化要计算word的文件的之后的结果的输出路径
System.exit(job.waitForCompletion(true) ? 0 : 1);
// 这里就是真正的去提交job到hadoop上去执行了,意思是指如果这个job真正的执行完了则主函数退出了,
// 若没有真正的执行完就退出了,则为非法退出
}
// Mapper<input_Key_Type,input_Value_Type,output_key_type,output_value_type>
// 这里的Text相当于jdk中的String,IntWritable相当于jdk的int类型
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
// 声明一个IntWritable变量,作计数用,每出现一个key,给其一个value=1的值
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();// 用来暂存map输出中的key值,Text类型的,故有此声明
/*
* 这里就是map函数,也用到了范型,它是和Mapper抽象类中的相对应的,此处的Object key, Text
* value的类型和上边的Object,Text是相对应的,而且最好一样,不然的话,多数情况运行时会报错。
*/
public void map(Object key, Text value, Context context) {
String[] str = value.toString().split(" ");
for (String s : str) {
word.set(s);// 出现一个单词就给它设成一个key并将其值设为1
try {
context.write(word, one);// 输出设成的key/value值
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException,
InterruptedException {
int sum = 0;
/*
* 由于map的打散,这里会得到如,{key,values}={"hello",{1,1,1,1,1,1,....}},这样的集合
* 这里需要逐一将它们的value取出来予以相加,取得总的出现次数,即为汇和
*/
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);// 将values的和取得,并设成result对应的值
context.write(key, result);
}
}
}
确认没错后,打成jar包
运行:
启动WinSCP,连上集群。把jar包放在自己的文件夹内,如 /home/tseg/zq。
创建文件 /user/zq/text.txt,里面写明输入输出地址,如/user/zq/t.txt;/user/zq/out。 然后根据输入地址(/user/zq/t.txt),创建相应的准备处理的文件(就是wordcount要处理的)。
在PuTTY中打开会话窗口。执行wordcount
tseg@dell1:~$ cd /home/tseg/zq
tseg@dell1:~/zq$ hadoop jar wordcount.jar
运行完毕后,列出输出目录表
tseg@dell1:~$ cd zq
tseg@dell1:~/zq$ hadoop fs -ls /user/zq/out
Found 2 items
drwxr-xr-x - tseg supergroup 0 2014-03-19 15:38 /user/zq/out/_logs
-rw-r--r-- 2 tseg supergroup 65 2014-03-19 15:39 /user/zq/out/part-r-00000
显示输出结果:
tseg@dell1:~/zq$ hadoop fs -cat /user/zq/out/part-r-00000
1
a 1
b 1
c 2
d 4
e 5
f 3
g 2
h 1
r 4
s 3
sd 1
t 2
w 1
y 2
yu 1