任务需求

统计HDFS上文件的wordcount,并将统计结果输出到HDFS

功能拆解

  • 读取HDFS文件
  • 业务处理(词频统计)
  • 缓存处理结果
  • 将结果输出到HDFS

数据准备

  • 事先往HDFS上传需要进行词频统计的文件word.txt、word2.txt(可以是多个)...
  • 假设目录是/user/hadoop/input/...

框架搭建

先把具体的功能框架搭建出来,再进行细节方面的编写。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;

public class HDFSWordCountDemo{
    public static void main(String[] args) throws Exception{
        // 1.读取HDFS文件
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"), conf, "hadoop");
        // 使用Java API取出HDFS指定目录下所有要进行词频统计的单词文件,false表示不需要递归
        RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("input"), false);
        // 用于循环取出多个单词文本
        while (files.hasNext()) {
            LocatedFileStatus file = files.next();
            FSDataInputStream in = fs.open(file.getPath());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = null; // readLine每次读取一行
            // 用于循环取出每个文本的每行内容
            while ((line = reader.readLine()) != null) {
                // 2.业务处理(词频统计)

                /**
                 * 功能:
                 *      此处要进行单词的词频统计功能
                 * 输入:
                 *      每次循环读取的是一个文件,输入的是该文件的一行内容line
                 * 输出:
                 *      把每行内容line按指定分割符分割,成为一个个独立单词,进行累加统计,多个文本累计,返回结果数组
                 */
            }
            reader.close();
            in.close();
        }
        // 3.缓存处理结果:把统计结果写入缓存
        // TODO...
        // 4.将结果输出到HDFS
        // 先在HDFS上创建一个空文本
        FSDataOutputStream out = fs.create(new Path("output/result.txt"));
        // 然后取出缓存中的内容,追加到该HDFS文本即可
        // TODO...
    }
}

词频统计实现

分为两步:1)实现上下文对象,用于保存每次的统计;2)词频统计功能的封装调用

  • 使用Map实现上下文对象
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义上下文对象,其实就是模仿缓存
 */
public class HDFSContext {

    private Map<Object,Object> cacheMap = new HashMap<>();

    // 用于从外部可以直接获取缓存
    public Map<Object,Object> getCacheMap(){
        return cacheMap;
    }

    /**
     * 写数据到缓存
     * @param key
     * @param value
     */
    public void write(Object key,Object value){
        cacheMap.put(key, value);
    }

    /**
     * 从缓存中读取数据
     * @param key
     * @return
     */
    public Object get(Object key){
        return cacheMap.get(key);
    }
}
  • 词频统计逻辑处理
// 自定义一个Mapper接口,封装词频统计功能
public interface HDFSMapper {
    /**
     * @param line 读取到的每一行数据
     * @param context 上下文对象/缓存
     */
    public void map(String line,HDFSContext context);
}

// 接口的功能实现
public class WordCountMapper implements HDFSMapper{
    @Override
    public void map(String line, HDFSContext context) {
        String[] words = line.split(" "); // 按空格切割,words是一行内容的单词数组
        for (String word : words) { // 遍历数组,取出每一个单词
            Object value = context.get(word);   // 取出缓存中的单词,
            if (value == null){             // 如果value为null,则说明缓存中没有该单词
                //不存在这个单词
                context.write(word,1);  // 第一次出现的单词,次数为1,并写入缓存
            }else {
                // 出现次数+1
                int v = Integer.parseInt(value.toString()); // 取出单词的已经出现次数,转成int
                context.write(word,v+1);    // 次数+1,并写入缓存
            }
        }
    }
}
  • 调用
// 先声明类对象
HDFSContext context = new HDFSContext();
HDFSMapper mapper = new WordCountMapper();

// while里调用
while ((line = reader.readLine()) != null) {
    mapper.map(line,context);
}

缓存处理结果

Map<Object,Object> contextMap = context.getCacheMap();

追加结果到HDFS

// 把Map集合转换为Set集合,进行迭代操作
Set<Map.Entry<Object, Object>> entries = contextMap.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
    // 取出key-value,即(word,次数),写入HDFS
    out.write((entry.getKey().toString()+"\t"+entry.getValue()+"\n").getBytes());
}
System.out.println("词频统计运行成功!");
out.close();
fs.close();

完整代码

package com.hadoop.hdfs.wordcount;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Map;
import java.util.Set;

public class HDFSWordCountDemo{
    public static void main(String[] args) throws Exception{
        // 1.读取HDFS文件
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"), conf, "hadoop");
        HDFSContext context = new HDFSContext();
        HDFSMapper mapper = new WordCountMapper();
        // 使用Java API取出HDFS指定目录下所有要进行词频统计的单词文件,false表示不需要递归
        RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("input"), false);
        // 用于循环取出多个单词文本
        while (files.hasNext()) {
            LocatedFileStatus file = files.next();
            FSDataInputStream in = fs.open(file.getPath());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = null; // readLine每次读取一行
            // 用于循环取出每个文本的每行内容
            while ((line = reader.readLine()) != null) {
                mapper.map(line,context);
            }
            reader.close();
            in.close();
        }
        // 3.缓存处理结果:把统计结果写入缓存
        Map<Object,Object> contextMap = context.getCacheMap();
        // 4.将结果输出到HDFS
        // 先在HDFS上创建一个空文本
        FSDataOutputStream out = fs.create(new Path("output/result.txt"));
        // 然后取出缓存中的内容,追加到该HDFS文本即可
        Set<Map.Entry<Object, Object>> entries = contextMap.entrySet();
        for (Map.Entry<Object, Object> entry : entries) {
            out.write((entry.getKey().toString()+"\t"+entry.getValue()+"\n").getBytes());
        }
        System.out.println("词频统计运行成功!");
        out.close();
        fs.close();

    }
}

查看运行结果

$ hadoop fs -cat output/*

使用HDFS完成wordcount词频统计的更多相关文章

  1. 初学Hadoop之WordCount词频统计

    1.WordCount源码 将源码文件WordCount.java放到Hadoop2.6.0文件夹中. import java.io.IOException; import java.util.Str ...

  2. Hadoop基础学习(一)分析、编写并执行WordCount词频统计程序

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jiq408694711/article/details/34181439 前面已经在我的Ubuntu ...

  3. 词频统计小程序-WordCount.exe

    一. 背景 ​ 最近顶哥为了完成学历提升学业中的小作业,做了一个词频统计的.exe小程序.因为当时做的时候网上的比较少,因此顶哥决定把自己拙略的作品发出来给需要的人提供一种思路,希望各位看官不要dis ...

  4. 使用SparkSQL编写wordCount的词频统计

    # 使用SparkSQL编写wordCount的词频统计 ## word.txt```hello hello scala sparkjava sql html java hellojack jack ...

  5. Hive简单编程实践-词频统计

    一.使用MapReduce的方式进行词频统计 (1)在HDFS用户目录下创建input文件夹 hdfs dfs -mkdir input 注意:林子雨老师的博客(http://dblab.xmu.ed ...

  6. hive进行词频统计

    统计文件信息: $ /opt/cdh-5.3.6/hadoop-2.5.0/bin/hdfs dfs -text /user/hadoop/wordcount/input/wc.input hadoo ...

  7. Hadoop之词频统计小实验

    声明:    1)本文由我原创撰写,转载时请注明出处,侵权必究. 2)本小实验工作环境为Ubuntu操作系统,hadoop1-2-1,jdk1.8.0. 3)统计词频工作在单节点的伪分布上,至于真正实 ...

  8. Hadoop上的中文分词与词频统计实践 (有待学习 http://www.cnblogs.com/jiejue/archive/2012/12/16/2820788.html)

    解决问题的方案 Hadoop上的中文分词与词频统计实践 首先来推荐相关材料:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-c ...

  9. MapReduce词频统计

    自定义Mapper实现 import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; impor ...

随机推荐

  1. vs code 的便捷使用

    鼠标滚动 改变字体大小 打开编辑器设置,搜索 editor.mouseWheelZoom  或者文本设置 自动保存 打开设置 搜索  autosave

  2. 读取导入csv csv报错iterable expected, not float

    示例代码import pandas as pdimport reimport csv data = pd.read_csv('nuojia.csv', encoding='utf-8')# print ...

  3. JS 基础知识点

    最近发现一个好东西,掘金小册,觉得里面的东西挺不错的,准备仔细阅读一下,提升下自己. 记录一下,随便加深点儿印象,主要内容源自于小册. 原始类型 原始类型也成为基本数据类型 boolean null ...

  4. BZOJ2300[HAOI2011]防线修建——非旋转treap+凸包(平衡树动态维护凸包)

    题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还犹豫不决,到底该把哪些城市作为保护对象呢?又由于 ...

  5. VS2010查看源码对应的汇编语言

    在学习c++中const关键字的过程中,经常会看到各种寄存器.汇编指令分析,像下面的图这样 左图是g++中反汇编的效果,右图是vs中反汇编的效果. 如果我们想要查看源码所对应的汇编语言,应该怎么操作呢 ...

  6. 【洛谷P4555】最长双回文串

    题目大意:给定一个长度为 N 的字符串 S,求 S 的最长双回文子串的长度,双回文子串定义为是 S 的一个子串,可以分成两个互不相交的回文子串. 题解:利用回文自动机 len 数组的性质,即:len ...

  7. Sublime Text3—自带快捷键介绍

    摘要: Sublime Text是个小巧便捷的编辑器,除了众多好用的插件外,还有它自带的快捷键,打代码事半功倍,不会用的赶紧看看吧! 其实菜单上都有,看不懂可以汉化,Key Bindings-Defa ...

  8. opencv+codeblocks +anaconda

    study from : https://www.jianshu.com/p/c16b7c870356 #include <cstdio> #include <cstdlib> ...

  9. MFC:编辑区 Edit 的属性及使用

    Edit Control 编辑控件是 MFC 中使用较多的控件之一 1. Edit 的属性 Acccept Files -> True 控件接受拖放文件 Multiline -> True ...

  10. static_assert与assert

    C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做静态断言. 其语法:static_assert(常量表达式,提示字符串). 如果第一个参数常量表达式的值为fals ...