資料分析案例——流量統計
阿新 • • 發佈:2018-12-17
使用java處理日誌檔案,完成需求。
簡介
http.log日誌檔案中,是電信運營商記錄使用者上網訪問某些網站行為的日誌記錄資料,一條資料中有多個欄位用空格或製表符分隔。 例如:"18611132889 http://v.baidu.com/tv 20 5000"是一條上網行為,第一個欄位代表手機號碼,第二個欄位代表請求網站的URL, 第三個欄位代表請求傳送的資料即上行流量(20位元組),第四個欄位代表伺服器響應給使用者的流量即下行流量(5000位元組)。 phone.txt是手機號段規則,是手機號碼對應地區城市和運營商的資料
需求
- 根據給的使用者上網日誌記錄資料,計算出總流量最高的網站Top3(網站例如:v.baidu.com
- 根據給的手機號段歸屬地規則,計算出總流量最高的省份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;
}
}