1. 程式人生 > >資料分析案例——流量統計

資料分析案例——流量統計

使用java處理日誌檔案,完成需求。

簡介

http.log日誌檔案中,是電信運營商記錄使用者上網訪問某些網站行為的日誌記錄資料,一條資料中有多個欄位用空格或製表符分隔。 例如:"18611132889 http://v.baidu.com/tv 20 5000"是一條上網行為,第一個欄位代表手機號碼,第二個欄位代表請求網站的URL, 第三個欄位代表請求傳送的資料即上行流量(20位元組),第四個欄位代表伺服器響應給使用者的流量即下行流量(5000位元組)。 phone.txt是手機號段規則,是手機號碼對應地區城市和運營商的資料

需求

  1. 根據給的使用者上網日誌記錄資料,計算出總流量最高的網站Top3(網站例如:v.baidu.com
    weibo.com)
  2. 根據給的手機號段歸屬地規則,計算出總流量最高的省份Top3

資料來源

專案結構

程式碼實現

SortUtils.java

package com.traffic;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;

public class SortUtils {

	/**
	 * 根據sun進行排序
	 * @param list
	 */
	public static void sortBySum
(List<Entry<String, Long>> list) { Collections.sort(list, new Comparator<Entry<String, Long>>() { @Override public int compare(Entry<String, Long> o1, Entry<String, Long> o2) { return o2.getValue() - o1.getValue() > 0 ? 1 : -1; } }); } }

TestMain1.java

需求1程式碼實現

package com.traffic;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMain1 {
	public static void main(String[] args) {
		// 獲取URL以及對應的流量和
		Map<String, Long> map = getUrlSum();
		// 轉化為list進行排序
		Set<Entry<String, Long>> entrySet = map.entrySet();
		List<Entry<String, Long>> list = new ArrayList<>(entrySet);
		// 排序
		SortUtils.sortBySum(list);
		/*
		 * for (Entry<String, Long> entry : list) { System.out.println(entry); }
		 */
		try (BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\data\\1"));) {
			for (int i = 0; i < 3; i++) {
				Entry<String, Long> entry = list.get(i);
				//使用toString方法轉化為toString
				bw.write(entry.toString());
				bw.newLine();
				System.out.println(list.get(i));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 獲取URL以及對應的流量和
	 * 
	 * @return
	 */
	private static Map<String, Long> getUrlSum() {
		// 用來儲存URL以及對應的流量資料
		Map<String, Long> map = new HashMap<>();
		try (BufferedReader br = new BufferedReader(new FileReader("D:\\data\\http.log"));) {
			String line = null;
			while ((line = br.readLine()) != null) {
				// System.out.println(line);
				String string = line.split("\t")[1];
				String[] split = string.split(" ");
				String oldUrl = split[0];
				String up = split[1];
				String down = split[2];
				String url = getUrlByRgex(oldUrl);

				Long upDown = Long.parseLong(up) + Long.parseLong(down);
				// 如果通過URL直接找到了流量則直接返回,否則就是0
				Long sum = map.getOrDefault(url, 0L);
				sum = sum + upDown;
				map.put(url, sum);

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 正則擷取URL
	 * 
	 * @param oldUrl
	 * @return
	 */
	private static String getUrlByRgex(String oldUrl) {
		Pattern compile = Pattern.compile("(\\w+\\.)?(\\w+\\.){1}\\w+");
		Matcher matcher = compile.matcher(oldUrl);
		while (matcher.find()) {
			return matcher.group();
		}
		return null;
	}
}

TestMain2.java

需求2程式碼實現

package com.traffic;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class TestMain2 {

	public static void main(String[] args) {
		// 通過檔案phone.txt獲取到手機號前七位對應的省份的map
		Map<String, String> map1 = getNumProvince();
		// System.out.println(map1.size());

		// 獲取手機號對應的流量
		Map<String, Long> map2 = getPNumSum();

		// 用來存放省份對應的流量
		Map<String, Long> map3 = new HashMap<>();

		Set<Entry<String, Long>> entrySet = map2.entrySet();
		for (Entry<String, Long> entry : entrySet) {
			String key = entry.getKey();
			Long value = entry.getValue();
			String pNum7 = key.substring(0, 7);
			String province = map1.get(pNum7);
			
			Long sum = map3.getOrDefault(province, 0L);
			sum+=value;
			map3.put(province, sum);
		}
		/*for (Entry<String, Long> entry : map3.entrySet()) {
			System.out.println(entry);
		}*/
		
		//排序 map -> list
		Set<Entry<String,Long>> entrySet2 = map3.entrySet();
		ArrayList<Entry<String,Long>> arrayList = new ArrayList<>(entrySet2);
		SortUtils.sortBySum(arrayList);
		/*for (Entry<String, Long> entry : arrayList) {
			System.out.println(entry);
		}*/
		for(int i = 0;i<3;i++) {
			System.out.println(arrayList.get(i));
		}
	}

	/**
	 * 獲取手機號對應的流量
	 * 
	 * @return
	 */
	private static Map<String, Long> getPNumSum() {
		Map<String, Long> map = new HashMap<>();
		try (BufferedReader br = new BufferedReader(new FileReader("D:/data/http.log"));) {
			String line = null;
			while ((line = br.readLine()) != null) {
				// System.out.println(line);
				String[] split = line.split("\t");
				String pNum = split[0];// 擷取???
				String[] split2 = split[1].split(" ");
				String up = split2[1];
				String down = split2[2];
				Long upDown = Long.parseLong(up) + Long.parseLong(down);
				// System.out.println(sum);
				// 相應的做累加
				Long sum = map.getOrDefault(pNum, 0L);
				sum = sum + upDown;
				map.put(pNum, sum);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 通過檔案phone.txt獲取到手機號前七位對應的省份的map
	 * 
	 * @return
	 */
	private static Map<String, String> getNumProvince() {
		Map<String, String> map = new HashMap<>();
		try (BufferedReader br = new BufferedReader(new FileReader("D:/data/phone.txt"));) {
			String line = null;
			br.readLine();// 跳過第一行
			while ((line = br.readLine()) != null) {
				// System.out.println(line);
				String[] split = line.split("\t");
				String pNum7 = split[1];
				String province = split[2];
				// System.out.println(province);
				map.put(pNum7, province);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

}

專案原始碼