海量日志数据,找出出现次数最多的IP地址。

来源:互联网 发布:网游在线人数数据 编辑:程序博客网 时间:2024/05/22 10:27

问题描述

有一个12G的文本文件,每行记录的是一个IP地址,现要找出这个文件中出现次数最多的那个ip。

代码实现

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. import java.io.BufferedReader;  
  2. import java.io.File;  
  3. import java.io.FileNotFoundException;  
  4. import java.io.FileReader;  
  5. import java.io.FileWriter;  
  6. import java.io.IOException;  
  7. import java.io.Serializable;  
  8. import java.util.ArrayList;  
  9. import java.util.HashMap;  
  10. import java.util.List;  
  11.   
  12. class IP implements Serializable {  
  13.   
  14.     private static final long serialVersionUID = -8903000680469719698L;  
  15.     private String ip = "";  
  16.     private int count;  
  17.   
  18.     public IP(String ip2, Integer integer) {  
  19.         this.ip = ip2;  
  20.         this.count = integer;  
  21.     }  
  22.   
  23.     public int getCount() {  
  24.         return count;  
  25.     }  
  26.   
  27.     public String getIp() {  
  28.         return ip;  
  29.     }  
  30.   
  31.     public void setCount(int count) {  
  32.         this.count = count;  
  33.     }  
  34.   
  35.     public void setIp(String ip) {  
  36.         this.ip = ip;  
  37.     }  
  38.   
  39. }  
  40.   
  41. /** 
  42.  * 1、海量日志数据,提取出某日访问百度次数最多的那个IP。 
  43.  *  
  44.  * 首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用映射的方法, 
  45.  * 比如模1000 
  46.  * ,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率 
  47.  * 。然后再在这1000个最大的IP中,找出那个频率最大的IP 
  48.  *  
  49.  * @author WilsonPeng 846106184@qq.com 
  50.  *  
  51.  */  
  52. public class No2 {  
  53.     static String fileLoc = "D:\\bigdata_ip.txt";  
  54.   
  55.     public static void findIp() throws IOException, ClassNotFoundException {  
  56.         long start = System.currentTimeMillis();  
  57.         hashToSmallFiles();  
  58.         long end1 = System.currentTimeMillis();  
  59.         System.out.println("将大文件映射成小文件,用时:" + (end1 - start) + "毫秒");  
  60.   
  61.         System.out.println("映射到小文件完成,开始统计每个小文件中出现频率最高的ip");  
  62.         long start1 = System.currentTimeMillis();  
  63.         List<IP> list = countEverySmallFile();  
  64.         long end2 = System.currentTimeMillis();  
  65.         System.out.println("统计所有文件共用时:" + (end2 - start1) + " 毫秒");  
  66.   
  67.         System.out.println("统计完成,开始计算所有ip中出现频率最高的ip");  
  68.         IP ip = calculateResult(list);  
  69.         System.out.println("访问次数最多的ip是:" + ip.getIp() + ":" + ip.getCount());  
  70.         long end = System.currentTimeMillis();  
  71.         System.out.println("公用时:" + (end - start) + "毫秒");  
  72.     }  
  73.   
  74.     /** 
  75.      * 从每个文件出现频率最高ip中,计算出所有文件中出现频率最高ip。 
  76.      *  
  77.      * @param list 
  78.      */  
  79.     private static IP calculateResult(List<IP> list) {  
  80.         IP[] ips = new IP[list.size()];  
  81.         ips = list.toArray(ips);  
  82.         int max = 0;  
  83.         for (int j = 1; j < ips.length; j++) {  
  84.             if (ips[j].getCount() > ips[max].getCount()) {  
  85.                 max = j;  
  86.             }  
  87.         }  
  88.         return ips[max];  
  89.     }  
  90.   
  91.     /** 
  92.      * 统计生成的每一个小文件,返回一个List,这个List的每一项就是每个小文件的统计结果,即每个小文件中出现频率最高的ip和出现次数 
  93.      *  
  94.      * @return 
  95.      * @throws FileNotFoundException 
  96.      * @throws IOException 
  97.      */  
  98.     private static List<IP> countEverySmallFile() throws FileNotFoundException, IOException {  
  99.         List<IP> list = new ArrayList<IP>();  
  100.         for (int i = 0; i < 1024; i++) {  
  101.             File file = new File(fileLoc + i + ".txt");  
  102.             if (file.exists()) {  
  103.                 long startTime = System.currentTimeMillis();  
  104.                 BufferedReader br1 = new BufferedReader(new FileReader(file));  
  105.                 String ip1 = "";  
  106.                 HashMap<String, Integer> hm = new HashMap<String, Integer>();  
  107.                 while ((ip1 = br1.readLine()) != null) {  
  108.                     if (!hm.containsKey(ip1)) {  
  109.                         hm.put(ip1, 1);  
  110.                     } else {  
  111.                         hm.put(ip1, hm.get(ip1) + 1);  
  112.                     }  
  113.                 }  
  114.   
  115.                 IP[] ips = new IP[hm.size()];  
  116.                 int index = 0;  
  117.                 for (String temp : hm.keySet()) {  
  118.                     ips[index] = new IP(temp, hm.get(temp));  
  119.                     index++;  
  120.                 }  
  121.                 int max = 0;  
  122.                 for (int j = 1; j < ips.length; j++) {  
  123.                     if (ips[j].getCount() > ips[max].getCount()) {  
  124.                         max = j;  
  125.                     }  
  126.                 }  
  127.                 list.add(ips[max]);  
  128.                 long endTime = System.currentTimeMillis();  
  129.                 System.out.println("已经统计文件:" + fileLoc + i + ".txt,用时:" + (endTime - startTime) + " 毫秒");  
  130.             }  
  131.         }  
  132.         return list;  
  133.     }  
  134.   
  135.     /** 
  136.      * 将打文件hash成1024个小文件 
  137.      *  
  138.      * @throws FileNotFoundException 
  139.      * @throws IOException 
  140.      */  
  141.     private static void hashToSmallFiles() throws FileNotFoundException, IOException {  
  142.         BufferedReader br = new BufferedReader(new FileReader(fileLoc));  
  143.         String ip = "";  
  144.         HashMap<String, FileWriter> fileWriters = new HashMap<String, FileWriter>();  
  145.         while ((ip = br.readLine()) != null) {  
  146.             int tmp = Math.abs(ip.hashCode() % 1024);  
  147.             String fileName = fileLoc + tmp + ".txt";  
  148.             FileWriter fw = null;  
  149.             if (fileWriters.containsKey(fileName)) {  
  150.                 fw = fileWriters.get(fileName);  
  151.             } else {  
  152.                 fw = new FileWriter(fileName, true);  
  153.                 fileWriters.put(fileName, fw);  
  154.             }  
  155.             fw.write(ip + "\n");  
  156.         }  
  157.         br.close();  
  158.         for (FileWriter ff : fileWriters.values()) {  
  159.             ff.close();  
  160.         }  
  161.     }  
  162.   
  163.     /** 
  164.      * 随机生成ip地址,生成大文本文件 
  165.      *  
  166.      * @throws IOException 
  167.      */  
  168.     private static void generateFile() throws IOException {  
  169.         FileWriter fw = new FileWriter(fileLoc, true);  
  170.         for (int i = 0; i < 100000000; i++) {  
  171.             for (int j = 0; j < 100000000; j++) {  
  172.                 fw.write(generateIp() + "\n");  
  173.             }  
  174.         }  
  175.         fw.close();  
  176.         System.out.println("done");  
  177.     }  
  178.   
  179.     /** 
  180.      * 随机生成ip地址 
  181.      *  
  182.      * @return 
  183.      */  
  184.     private static String generateIp() {  
  185.         String ip = "";  
  186.         for (int i = 0; i < 4; i++) {  
  187.             int temp = (int) (Math.random() * 255);  
  188.             ip += temp + ".";  
  189.         }  
  190.         return ip.substring(0, ip.length() - 1);  
  191.     }  
  192.   
  193.     public static void main(String[] args) {  
  194.         try {  
  195.             findIp();  
  196.         } catch (Exception e) {  
  197.             // TODO Auto-generated catch block  
  198.             e.printStackTrace();  
  199.         }  
  200.     }  
  201.   
  202. }  


原创粉丝点击