思路參考july博客http://blog.csdn.net/v_july_v/article/details/7382693
1、海量日誌數據,提取出某日訪問百度次數最多的那個IP。
因爲內存容量有限。所以需對大的文件進行切割。在分割文件時應使相同的IP保存到同一個文件中。可以採用取模操作。
注意:相同的IP必須存儲到相同的文件中
因爲每個IP(相當於字符串)對應了一個hashcode,相同的IP的hashcode肯定相同,通過hashcode對某個數取模,比如100.,這樣原文件分割成100個文件。
根據取模的結果存儲到相應的文件中。相同的IP會存儲到同一個文件中。分割後的文件大小大約爲原來的1/n(若對n取模),若對100取模大約爲原文件的1/100。如果分割
後的文件中可能有部分文件內存中還裝載(load)不下,可以對該文件繼續分割直至內存可以裝下爲止。(比如對該文件繼續對2求模)
對於分割後的文件,求每個文件上出現次數最多的IP。此時可以用hashmap存儲每個IP出現的次數。key存儲爲IP字符串,value爲該字符串出現的次數。每訪問文件中的一條記錄(IP),若該IP在hashmap中已存在,相應的value增加1。否則向hashmap中插入(put)一條新的記錄。
統計該hashmap上擁有最大value的項
最後比較所有文件上訪問最多的IP便求出了訪問次數最多的IP
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
public class MassiveIP {
//generate the massive numbers of IPs
public void generateIP(String fileName){
PrintWriter out =null;
try {
out=new PrintWriter(fileName);
String s;
Random r=new Random();
for(int i=0;i<100000000;i++){
s="159.227.";
s+=r.nextInt(256)+"."+r.nextInt(256);
out.println(s);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (out != null)
out.close( );
}
}
//split the file to make it fit into the memory
public void FileSplit(String fileName){
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader (fileName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PrintWriter[] out=new PrintWriter[100];
for(int i=0;i<100;i++)
try {
//specify split file name
out[i]=new PrintWriter(fileName+i);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String IP = null;
try {
while((IP =reader.readLine())!= null ) {
IP=reader.readLine();
int fileNum=IP.hashCode()%100;
fileNum=(fileNum>=0?fileNum:fileNum+100);
// System.out.println(fileNum);
out[fileNum].println(IP);
}
for(int i=0;i<100;i++)
out[i].close();
//}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//find IP with the largest number of occurrence
public Map.Entry<String,Integer> statitics(String fileName){
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader (fileName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HashMap<String,Integer> map=new HashMap<String,Integer>();
String IP = null;
try {
while((IP =reader.readLine())!= null){
//to judge whether the IP is already
//existed in the HashMap
if(map.containsKey(IP)){
map.put(IP, map.get(IP)+1);
}
else
map.put(IP,1);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Entry in HashMap with the maximum value
//which means the IP with the largest occurrence
Map.Entry<String,Integer> maxEntry=null;
for (Map.Entry<String,Integer> entry : map.entrySet()){
if (maxEntry == null || entry.getValue()>maxEntry.getValue()) {
maxEntry = entry;
}
}
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return maxEntry;
}
public static void main(String[] args){
MassiveIP m=new MassiveIP();
String FileName="D://Data//test.txt";
m.generateIP(FileName);
m.FileSplit(FileName);
List<Map.Entry<String,Integer>>l
=new ArrayList<Map.Entry<String,Integer>>();
for(int i=0;i<100;i++)
l.add(m.statitics(FileName+i));
Map.Entry<String,Integer>maxEntry=l.get(0);
for(int j=1;j<100;j++){
if(l.get(j).getValue()>maxEntry.getValue())
maxEntry=l.get(j);
}
System.out.println(maxEntry.getKey());
System.out.println(maxEntry.getValue());
}
}