搭建HDFS项目框架实现词频统计

!!!我的.txt文件以tap作为分割不是空格
1.框架结构如下
在这里插入图片描述
2.

package bigdata.hdfs;
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;

/**
 * 使用HDFS API完成wordcount统计
 *
 * 需求:统计HDFS上的文件 WC,然后将统计结果输出到HDFS
 * 功能拆解:
 * 1) 读取HDFS上的文件
 * 2)业务处理(词频统计):对文件中的每一行数据都要进行业务处理(按照分隔符分割)==》Mapper
 * 3)将处理的结果缓存起来 ==》Context
 * 4)将处理的结果输出到HDFS  ==>HDFS API
 */
public class HDFSWCApp01 {
    public static void main(String[] args) throws Exception{

        //(1)读取HDFS上的文件 ==> HDFS API
        Path input=new Path("/hdfsapi/test/hello.txt");

        //获取要操作的HDFS文件系统
        FileSystem fs=FileSystem.get(new URI("hdfs://192.168.19.3:8020"),new Configuration(),"jerry");

        RemoteIterator<LocatedFileStatus> iterator=fs.listFiles(input,false);//迭代器,是集合专有的遍历方式
        ImmocMapper mapper =new WordCountMapper();
        ImmocContext context= new ImmocContext(); //new一个上下文

        while ((iterator.hasNext())){
            LocatedFileStatus file=iterator.next();
            FSDataInputStream in=fs.open(file.getPath());
            BufferedReader reader =new BufferedReader(new InputStreamReader(in));

            String line="";
            while ((line=reader.readLine())!=null){
                //(2)业务处理(词频统计)
                mapper.map(line,context);

            }

            reader.close();
            in.close();
        }

        //Map 键值对:每个键后面对应着相应的值, 当按下相应的键时, 就会输出相应的结果
        //TODO (3)将处理的结果缓存起来 Map
        //Map<Object,Object> contextMap= new HashMap<Object, Object>();

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

        //(4)将结果输出到HDFS ==>  HDFS API
        Path output=new Path("/hdfsapi/output");
        FSDataOutputStream out = fs.create(new Path(output,new Path("wa.out")));

        //TODO 将第三步缓存中的内容输出到out中去
        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());

        }
        out.close();
        fs.close();
        System.out.println("运行成功");

    }
}

package bigdata.hdfs;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义上下文,缓存
 */
public class ImmocContext {
    private Map<Object,Object> cacheMap = new HashMap<Object, Object>();

    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);
    }

}

package bigdata.hdfs;

public interface ImmocMapper {
    /*
    * @param line 读取到每一行数据
    * @param context 上下文/缓存
    * */
    public  void  map(String line,ImmocContext context);
}

package bigdata.hdfs;

public class WordCountMapper implements ImmocMapper {
    public void map(String line, ImmocContext context) {
       String[] words = line.split("\t");

        for (String word : words){
            Object value=context.get(word);
            if (value==null){ //表示没有出现过该单词
                context.write(word,1);
            } else {
                int v=Integer.parseInt(value.toString());
                context.write(word,v+1); //取出单词的次数+1
            }
        }
    }
}

验证:
在这里插入图片描述
浏览器访问50070端口也可验证!
硬编码在编程过程中是非常忌讳的分享一下自定义文件配置重构代码
1.
在这里插入图片描述

2.在resources配置文件夹新建配置文件(Mark Directory as)
在这里插入图片描述
wc.properties

INPUT_PATH=/hdfsapi/test/hello.txt
OUTPUT_PATH=/hdfsapi/output
OUTPUT_FILE=wa.out2
HDFS_URL=hdfs://192.168.19.3:8020

3.读取配置文件

package bigdata.hdfs;

import java.io.IOException;
import java.util.Properties;

/**
 *读取属性配置文件
 */
public class ParamsUtils {
    private  static Properties properties=new Properties();
    static {

        try {
            properties.load(ParamsUtils.class.getClassLoader().getResourceAsStream("wc.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public  static Properties getProperties() throws Exception{
        return  properties;
    }

    public static void main(String[] args)  throws Exception{
       System.out.println( getProperties().getProperty("INPUT_PATH"));

    }

}

4.定义常量

package bigdata.hdfs;

/**
 * 常量
 */
public class Constants {
    public static  final  String INPUT_PATH="INPUT_PATH";

    public static  final  String OUTPUT_PATH="OUTPUT_PATH";

    public static  final  String OUTPUT_FILE="OUTPUT_FILE";

    public static  final  String HDFS_URL="HDFS_URL";

}

5.实现

package bigdata.hdfs;

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.Properties;
import java.util.Set;

/**
 * 使用HDFS API完成wordcount统计
 *
 * 需求:统计HDFS上的文件 WC,然后将统计结果输出到HDFS
 * 功能拆解:
 * 1) 读取HDFS上的文件
 * 2)业务处理(词频统计):对文件中的每一行数据都要进行业务处理(按照分隔符分割)==》Mapper
 * 3)将处理的结果缓存起来 ==》Context
 * 4)将处理的结果输出到HDFS  ==>HDFS API
 */
public class HDFSWCApp02 {
    public static void main(String[] args) throws Exception{

        //(1)读取HDFS上的文件 ==> HDFS API

        Properties properties=ParamsUtils.getProperties();
        Path input=new Path(properties.getProperty(Constants.INPUT_PATH));

        //获取要操作的HDFS文件系统
        FileSystem fs=FileSystem.get(new URI(properties.getProperty(Constants.HDFS_URL)),new Configuration(),"jerry");

        RemoteIterator<LocatedFileStatus> iterator=fs.listFiles(input,false);//迭代器,是集合专有的遍历方式
        ImmocMapper mapper =new WordCountMapper();
        ImmocContext context= new ImmocContext(); //new一个上下文

        while ((iterator.hasNext())){
            LocatedFileStatus file=iterator.next();
            FSDataInputStream in=fs.open(file.getPath());
            BufferedReader reader =new BufferedReader(new InputStreamReader(in));

            String line="";
            while ((line=reader.readLine())!=null){
                //(2)业务处理(词频统计)
                mapper.map(line,context);

            }

            reader.close();
            in.close();
        }

        //Map 键值对:每个键后面对应着相应的值, 当按下相应的键时, 就会输出相应的结果
        //TODO (3)将处理的结果缓存起来 Map
        //Map<Object,Object> contextMap= new HashMap<Object, Object>();

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

        //(4)将结果输出到HDFS ==>  HDFS API
        Path output=new Path(properties.getProperty(Constants.OUTPUT_PATH));
        FSDataOutputStream out = fs.create(new Path(output,new Path(properties.getProperty(Constants.OUTPUT_FILE))));

        //TODO 将第三步缓存中的内容输出到out中去
        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());

        }
        out.close();
        fs.close();
        System.out.println("运行成功");

    }
}

发布了5 篇原创文章 · 获赞 3 · 访问量 341

猜你喜欢

转载自blog.csdn.net/weixin_42641465/article/details/104867883