import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.apache.commons.io.FileUtils; import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import backtype.storm.utils.Utils; /**
* 单词计数
* 监控d:\\test目录下面的文件,统计单词出现的总次数
* 当有新文件出现的时候,也要能解析出来
*
* @author Administrator
*
*/
public class LocalTopologyWordCount { /**
* spout需要继承baserichspout,实现未实现的方法
* @author Administrator
*
*/
public static class DataSourceSpout extends BaseRichSpout{
private Map conf;
private TopologyContext context;
private SpoutOutputCollector collector; /**
* 初始化方法,只会执行一次
* 在这里面可以写一个初始化的代码
* Map conf:其实里面保存的是topology的一些配置信息
* TopologyContext context:topology的上下文,类似于servletcontext
* SpoutOutputCollector collector:发射器,负责向外发射数据(tuple)
*/
@Override
public void open(Map conf, TopologyContext context,
SpoutOutputCollector collector) {
this.conf = conf;
this.context = context;
this.collector = collector;
} /**
* 这个方法是spout中最重要的方法,
* 这个方法会被storm框架循环调用,可以理解为这个方法是在一个while循环之内
* 每调用一次,会向外发射一条数据
*/
@Override
public void nextTuple() {
//获取指定目录下面的新文件,
Collection<File> listFiles = FileUtils.listFiles(new File("d:\\test"), new String[]{"txt"}, true);
//分别读取每个文件
for (File file : listFiles) {
try {
List<String> readLines = FileUtils.readLines(file);
for (String line : readLines) {
//把每一行封装成一个tuple,发射出去
this.collector.emit(new Values(line));
}
FileUtils.moveFile(file, new File(file.getAbsolutePath()+System.currentTimeMillis()));//给文件该名字,否则会一直处理这个文件.
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 声明输出字段
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
//给values中的数据起个名字,方便后面的bolt从这个values中取数据
//fields中定义的参数和values中传递的数值是一一对应的
declarer.declare(new Fields("line"));
} } /**
* 自定义bolt需要实现baserichbolt
* @author Administrator
*
*/
public static class SplitBolt extends BaseRichBolt{
private Map stormConf;
private TopologyContext context;
private OutputCollector collector; /**
* 和spout中的open方法意义一样
*/
@Override
public void prepare(Map stormConf, TopologyContext context,
OutputCollector collector) {
this.stormConf = stormConf;
this.context = context;
this.collector = collector;
} /**
* 是bolt中最重要的方法,当spout发射一个tuple出来,execute也会被调用,需要对spout发射出来的tuple进行处理
*/
@Override
public void execute(Tuple input) {
//获取每一行数据进行切割
String line = input.getStringByField("line");
String[] splits = line.split("\t");
//把切割出来的单词一个一个发射出去
for (String word : splits) {
this.collector.emit(new Values(word));
} } //在这没必要定义了,因为execute方法中没有向外发射tuple,所以就不需要声明了。
//如果nextTuple或者execute方法中向外发射了tuple,那么declareOutputFields必须要声明,否则不需要声明
/**
* 声明输出字段
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
} } /**
* 自定义bolt需要实现baserichbolt
* @author Administrator
*
*/
public static class CountBolt extends BaseRichBolt{
private Map stormConf;
private TopologyContext context;
private OutputCollector collector; /**
* 和spout中的open方法意义一样
*/
@Override
public void prepare(Map stormConf, TopologyContext context,
OutputCollector collector) {
this.stormConf = stormConf;
this.context = context;
this.collector = collector;
} HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
/**
* 是bolt中最重要的方法,当spout发射一个tuple出来,execute也会被调用,需要对spout发射出来的tuple进行处理
*/
@Override
public void execute(Tuple input) {
//获取每一个单词
String word = input.getStringByField("word");
//在map中进行统计
Integer integer = hashMap.get(word);
if(integer==null){
integer=0;
}
integer++;
hashMap.put(word, integer);
//把这个统计结果打印到控制台
Utils.sleep(1000);
System.out.println("=========================================");
for (Entry<String, Integer> entry : hashMap.entrySet()) {
System.out.println(entry);
}
} //在这没必要定义了,因为execute方法中没有向外发射tuple,所以就不需要声明了。
//如果nextTuple或者execute方法中向外发射了tuple,那么declareOutputFields必须要声明,否则不需要声明
/**
* 声明输出字段
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
} }
/**
* 注意:在组装topology的时候,组件的id在定义的时候,名称不能以__开头。__是系统保留的
* @param args
*/
public static void main(String[] args) {
//组装topology
TopologyBuilder topologyBuilder = new TopologyBuilder();
topologyBuilder.setSpout("spout1", new DataSourceSpout());
//.shuffleGrouping("spout1"); 表示让MyBolt接收MySpout发射出来的tuple
topologyBuilder.setBolt("bolt1", new SplitBolt()).shuffleGrouping("spout1");
topologyBuilder.setBolt("bolt2", new CountBolt()).shuffleGrouping("bolt1"); //创建本地storm集群
LocalCluster localCluster = new LocalCluster();
localCluster.submitTopology("wordCountTopology", new Config(), topologyBuilder.createTopology());
}
}

Strom实现单词统计代码的更多相关文章

  1. Storm实现单词统计代码

    import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.HashM ...

  2. 2、 Spark Streaming方式从socket中获取数据进行简单单词统计

    Spark 1.5.2 Spark Streaming 学习笔记和编程练习 Overview 概述 Spark Streaming is an extension of the core Spark ...

  3. Storm基础概念与单词统计示例

    Storm基本概念 Storm是一个分布式的.可靠地.容错的数据流处理系统.Storm分布式计算结构称为Topology(拓扑)结构,顾名思义,与拓扑图十分类似.该拓扑图主要由数据流Stream.数据 ...

  4. java课程课后作业190502之单词统计续集

    第1步:输出单个文件中的前 N 个最常出现的英语单词. 功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列. 功能2: 指定文件目录,对目录下每一个文件执行统 ...

  5. Spark入门(三)--Spark经典的单词统计

    spark经典之单词统计 准备数据 既然要统计单词我们就需要一个包含一定数量的文本,我们这里选择了英文原著<GoneWithTheWind>(<飘>)的文本来做一个数据统计,看 ...

  6. java源码——文件读写和单词统计

    本文要解决的问题:"键盘输入一段英语语句,将这段话写入content.txt中,然后输出这段话,并且统计语句中英文单词的数目以及各个单词出现的次数." 分析问题知,核心是文件读写和 ...

  7. Java实现单词统计

    原文链接: https://www.toutiao.com/i6764296608705151496/ 单词统计的是统计一个文件中单词出现的次数,比如下面的数据源 其中,最终出现的次数结果应该是下面的 ...

  8. MapReduce 单词统计案例编程

    MapReduce 单词统计案例编程 一.在Linux环境安装Eclipse软件 1.   解压tar包 下载安装包eclipse-jee-kepler-SR1-linux-gtk-x86_64.ta ...

  9. VS2010统计代码行数 [转]

    按CTRL+SHIFT+F (Find in files),勾上支持正则表达式,然后输入搜索内容:  ^:b*[^:b#/]+.*$ 以上表达式的统计可做到:#开头 和 /开头 或者 空行 都不计入代 ...

随机推荐

  1. HTML5中script的async属性异步加载JS

    HTML5中script的async属性异步加载JS     HTML4.01为script标签定义了5个属性: charset 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer 可 ...

  2. oracle:自定义多行合并聚合函数

    原始表 COUNTRY CITY            -------------------- -------------- 中国 台北              中国 香港             ...

  3. CT值及CT常用窗宽、窗位 [转]

    一.常用CT值 CT值的含义是:每个反应管内的荧光信号达到设定的域值时所经历的循环数.研究表明,每个模板的Ct值与该模板的起始拷贝数的 对数存在线性关系,起始拷贝数越多,Ct值越小.利用已知起始拷贝数 ...

  4. Function.caller

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/caller 非标准 ...

  5. Use jQuery to hide a DIV when the user clicks outside of it

    http://stackoverflow.com/questions/1403615/use-jquery-to-hide-a-div-when-the-user-clicks-outside-of- ...

  6. 转载:Erlang 资源

    Erlang资源 erlang豆瓣广播

  7. CloudStack4.2 二级镜像存储测试

    //添加二级存储{ "addimagestoreresponse": { "imagestore": { "id": "2dda4 ...

  8. javascript之冒泡算法

    今天看了js中数组的方法,其中sort()方法用于排序,就让我想到学C语言的时候有一个冒泡算法,就想用js写一个. <script> var arr=[1,30,20,40,21,31,1 ...

  9. 机器学习笔记之人工神经网络(ANN)

    人工神经网络(ANN)提供了一种普遍而且实际的方法从样例中学习值为实数.离散值或向量函数.人工神经网络由一系列简单的单元相互连接构成,其中每个单元有一定数量的实值输入,并产生单一的实值输出. 上面是一 ...

  10. 初步认识pg_control文件之一

    这个据说是PostgreSQL的control file. 到底如何呢,先看看改名后如何,把pg_control文件改名,然后启动 Postgres,运行时得到信息: [postgres@pg101 ...