URL区域访问量案例

第一部分 : 案例概述 : (需要access.log 和 ip.txt 虚拟文件)
给定的access.log是电信运营商的用户上网数据,第一个字段是时间, 第二个字段是ip地址,第三个字段是访问的网站,其他字段可以忽略不计.

ip.txt是ip地址和归属地的规则数据,里面的数据是根据ip地址的十进制从低到高排序。

第一个字段是网段的起始IP地址,
第二个字段是网段的结束IP地址,
第三个字段是网段的起始IP地址对应的十进制,
第四个字段是网段的结束IP地址对应的十进制,
第五个字段代表洲,
第六个代表国家,
第七个代表省,
第八个代表城市,
第九个区域,
第十个运营商。
其他字段可以忽略不计。
要求:
通过计算access.log中的用户行为数据,统计出各个省份访问量(一次请求记作一次独立的访问量),并按照各个省份的访问量的从高到低进行排序
步骤分析
根据Log数据获取所有的ip数据 根据ip去ip的规则数据中查询区域或者运营商数据
1 读取ip规则数据 将每条数据封装在bean里面 把所有的数据封装在list中
2 将ip转成长整型数据
3 使用二分查找查IpBean —–> 结果集 Map
代码实现 :

第二部分 : 代码实现
1.用IpBean来封装数据;
package com.doit.examle3;

public class IpBean {
// 1.0.8.0|1.0.15.255|16779264|16781311|亚洲|中国|广东|广州||电信

private String startIp;
private String endIp;
private Long startLongIp;
private Long endLongIp;
/** 洲 */
private String zhou;
private String country;
private String province;
private String city;
private String area;
/** 运营商 */
private String isp;

public void set(String startIp, String endIp, Long startLongIp, Long endLongIp, String zhou, String country,
        String province, String city, String area, String isp) {
    this.startIp = startIp;
    this.endIp = endIp;
    this.startLongIp = startLongIp;
    this.endLongIp = endLongIp;
    this.zhou = zhou;
    this.country = country;
    this.province = province;
    this.city = city;
    this.area = area;
    this.isp = isp;
}

public String getStartIp() {
    return startIp;
}

public void setStartIp(String startIp) {
    this.startIp = startIp;
}

public String getEndIp() {
    return endIp;
}

public void setEndIp(String endIp) {
    this.endIp = endIp;
}

public Long getStartLongIp() {
    return startLongIp;
}

public void setStartLongIp(Long startLongIp) {
    this.startLongIp = startLongIp;
}

public Long getEndLongIp() {
    return endLongIp;
}

public void setEndLongIp(Long endLongIp) {
    this.endLongIp = endLongIp;
}

public String getZhou() {
    return zhou;
}

public void setZhou(String zhou) {
    this.zhou = zhou;
}

public String getCountry() {
    return country;
}

public void setCountry(String country) {
    this.country = country;
}

public String getProvince() {
    return province;
}

public void setProvince(String province) {
    this.province = province;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public String getArea() {
    return area;
}

public void setArea(String area) {
    this.area = area;
}

public String getIsp() {
    return isp;
}

public void setIsp(String isp) {
    this.isp = isp;
}

@Override
public String toString() {
    return "IpBean [startIp=" + startIp + ", endIp=" + endIp + ", startLongIp=" + startLongIp + ", endLongIp="
            + endLongIp + ", zhou=" + zhou + ", country=" + country + ", province=" + province + ", city=" + city
            + ", area=" + area + ", isp=" + isp + "]";
}

}

2.写一个工具类 : IpUtils
package com.doit.examle3;

import java.util.List;

public class IpUtils {

/**
 * 使用静态代码块来初始化list<IpBean>
 */
static List<IpBean> list = null;
static {// static确保只读一次
    try {
        list = ReadIp.getIpInfo();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * 根据字符串ip返回IpBean
 * 
 * @param ip
 * @return
 */
public static IpBean getIpBean(String ip) {
    long ipLong = paseIpToLong(ip);

    // 二分查找
    int left = 0;
    int right = list.size() - 1;
    int middle;
    while (left <= right) {
        middle = (left + right) / 2;//middle的计算必须放在while循环体内,这样才能保证每次的引用偏移
        IpBean ipBean = list.get(middle);
        Long startLongIp = ipBean.getStartLongIp();
        Long endLongIp = ipBean.getEndLongIp();

        if (ipLong < startLongIp) {
            right = middle - 1;
        }

        if (ipLong > endLongIp) {
            left = middle + 1;
        }

        if (ipLong >= startLongIp && ipLong <= endLongIp) {
            return ipBean;
        }
    }
    return null;
}

/**
 * 把字符串ip转成long值
 * 
 * @param ip
 *            要转的字符串ip
 * @return
 */
public static long paseIpToLong(String ip) {
    long newIP = 0l;
    if (ip == null) {
        return newIP;
    }
    String[] split = ip.split("\\.");
    if (split.length == 4) {
        for (int i = 0; i < split.length; i++) {
            long l = Long.parseLong(split[i]);
            newIP |= l << ((3 - i) << 3);
        }
    }
    return newIP;
}

}

3.处理 ip.txt 文件
package com.doit.examle3;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class ReadIp {

/**
 * 封装数据 : 把ip的信息封装到IpBean,然后把IpBean放入到List<IpBean>,可以对list进行排序
 * 
 * @return
 * @throws Exception
 */
public static List<IpBean> getIpInfo() throws Exception {
    List<IpBean> list = new ArrayList<>();

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:/data/y/ip.txt"), "UTF-8"));
    String line = null;
    while ((line = br.readLine()) != null) {
        // 对读取的每行数据做业务处理 : 用 "\|" 切割
        String[] split = line.split("\|");

        // 把数据封装到IpBean
        String startIp = split[0];
        String endIp = split[1];
        Long startLongIp;
        Long endLongIp;

        try {
            startLongIp = Long.parseLong(split[2]);
            endLongIp = Long.parseLong(split[3]);
        } catch (Exception e) {// 过滤"坏数据"
            continue;
        }

        String zhou = split[4];
        String country = split[5];
        String province = split[6];
        String city = split[7];
        String area = split[8];
        String isp = split[9];

        IpBean bean = new IpBean();
        bean.set(startIp, endIp, startLongIp, endLongIp, zhou, country, province, city, area, isp);

        // 把bean存放到List<IpBean>
        list.add(bean);

    }
    br.close();
    return list;
}

}

4.处理 access.log 文件
package com.doit.examle3;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class ReadLog {

/**
 * 根据日志文件获取结果map : (k,v)<-->Map<String, Integer>(省份, 该省的访问量)
 * 
 * @return
 * @throws Exception
 */
public static Map<String, Integer> getLogInfo() throws Exception {

    Map<String, Integer> map = new HashMap<>();
    Map<String, Integer> resMap = new LinkedHashMap<>();// 使用LinkedHashMap来接收排序结果

    BufferedReader br = new BufferedReader(
            new InputStreamReader(new FileInputStream("D:/data/y/access.log"), "UTF-8"));
    // 读取日志文件
    String line = null;
    while ((line = br.readLine()) != null) {
        // 对读取的每行数据做业务处理 :
        String[] split = line.split("\|");
        // 获取ip
        String ip = split[1];

        /**
         * 根据ip获取IpBean
         */
        IpBean ipBean = IpUtils.getIpBean(ip);
        String p = ipBean.getProvince();

        Integer count = map.getOrDefault(p, 0);// 获取每个省份的访问量
        map.put(p, ++count);
    }

    /**
     * 按照访问量从高低低排序,并放入LinkedHashMap
     */
    Set<Entry<String, Integer>> entrySet = map.entrySet();
    ArrayList<Entry<String, Integer>> list = new ArrayList<>(entrySet);
    Collections.sort(list, (o1, o2) -> o2.getValue() - o1.getValue());

    // 遍历排好序的list,放入resMap
    for (Entry<String, Integer> entry : list) {
        resMap.put(entry.getKey(), entry.getValue());
    }

    br.close();
    return resMap;
}

}

*5.测试类*
package com.doit.examle3;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class TestMain {

public static void main(String[] args) throws Exception {
    Map<String, Integer> map = ReadLog.getLogInfo();

    Set<Entry<String, Integer>> entrySet = map.entrySet();
    for (Entry<String, Integer> entry : entrySet) {
        System.out.println(entry);
    }
}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值