上一篇是:單線程解析文件,根據文件關鍵詞進行統計,並將結果輸出(二)
完成了獲取文件輸入,並將每一行分發到對應的處理器的工具類,本次完成對應的三個工具類的實現。
一、首先實現三個需要解析的文件的bean類:自己實現get和set方法
<span style="font-size:18px;">/**
待解析的loadFile關鍵字對應的bean
以/t劃分成四部分,其中第二部分用空格分開成三部分
**/
public class LoadFile
{
private String key;//關鍵字
private String userName;//用戶名
private String reason;//加載文件失敗的原因
private String fileName;//加載失敗的文件名
private String ip;//加載失敗的ip
private String time;//加載失敗的時間
}
/**
待解析的udpconnect關鍵字對應的bean類;
以/t劃分成四部分,其中第二部分用空格分開成三部分
**/
public class UdpConnection
{
private String key;
private String userName;
private String flag;
private String explain;
private String ip;
private String time;
}</span>
二、完成對應的抽象接口:
瞭解了每個待解析關鍵詞的結構和創建了對應的bean,此時可以進行對應bean類的工具類實現。
根據本系列文章(一)中分析,對應的工具類都可以抽象成爲一個interface:輸入——輸出,對應接口如下:
<span style="font-size:18px;">public interface StatHandler<T>
{
/**
* 輸出結果
*/
public void output();
/**
* allstathandler 輸入一行數據
* @param t
*/
public void input(T t);
}</span>
其中爲了代碼的可擴展性和可讀性,應在工具類中增加內部類來解析該行數據,並且封裝成對應的bean類返回給input(T t)來處理數據,
每個工具類都有以上的需求,所以可以抽象出一個interface,該接口的思想是,一行數據進來,如果該數據正確,則對該數據進行解析,
並封裝成對應的bean類返回。
<span style="font-size:18px;">public interface InsideClass
{
/**
判斷本條數據是否正確
**/
public boolean judge(String[]);
/**
若本條數據正確,則返回對應數據的bean類型
**/
public <T>T getObject(String[]t);
}</span>
三、實現工具類:
完成上述思路上的準備可以開始寫工具類了
<span style="font-size:18px;">package com.zsj.test.daos;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import com.zsj.test.beans.LoadFile;
import com.zsj.test.interfaces.InsideClass;
import com.zsj.test.interfaces.StatHandler;
import com.zsj.test.tools.CommondTools;
public class LoadFileStatHandler implements StatHandler<String[]> {
private Vector<String>userSet=new Vector<>();//存放不同用戶
private Vector<String>ipSet=new Vector<>();//存放不同的ip
private ConcurrentHashMap<String,Integer>fileSet=new ConcurrentHashMap<>();//存放不同文件的加載失敗數
@Override
public void output() {
System.out.println("Load file stat:");
System.out.println("UserCount:" + userSet.size());
System.out.println("IP_Count:" + ipSet.size());
System.out.println("------------------------------------");
System.out.println("加載失敗的文件和加載失敗的次數爲:");
Set<String> set=fileSet.keySet();
Iterator<String> iter = set.iterator();
while (iter.hasNext()) {
String next=(String) iter.next();
System.out.println("fileName:" +next);
System.out.println("fileName_Count:" +fileSet.get(next));
}
System.out.println("------------------------------------");
}
@Override
public synchronized void input(String[] t) {
// TODO Auto-generated method stub
try
{
getLoadFile getLoadFile=new getLoadFile();//實例化內部類
LoadFile loadFile=getLoadFile.getObject(t);//進行解析,取得loadFile對象
if(loadFile!=null)//若該數據正確,則loadFIle對象不爲空
{
//利用loadFile對象,進行判斷
if(!userSet.contains(loadFile.getUserName()))//如果該用戶名不存在,則加入
{
userSet.add(loadFile.getUserName());
}
if(!ipSet.contains(loadFile.getIp()))//如果ip不存在,則加入
{
ipSet.add(loadFile.getIp());
}
if(!fileSet.containsKey(loadFile.getFileName()))
{
fileSet.put(loadFile.getFileName(),1);
}else
{
fileSet.put(loadFile.getFileName(),fileSet.get(loadFile.getFileName())+1);
}
}
}catch(Exception e)
{
e.printStackTrace();
}
}
//內部類的作用是對輸入進行解析,生成我們想要的數據類型,定義了類型,成員變量就會有意義,看代碼的時候也會很清晰,但下面的類其實還是字符串數組,沒有意義的
private class getLoadFile implements InsideClass
{
private final int secondPreventionCount=3;//第二次解析得到數據,正確爲3位
private final int firstPreventionCount=4;//第一次解析得到的數據,正確爲4位
private String[]abc=null;//解析第二位得到的字符集合
private LoadFile loadFile=new LoadFile();//生成loadFile實例
/**
* 進行解析,生成對應的loadFile對象
*/
@SuppressWarnings("unchecked")
@Override
public <T> T getObject(String[]t)
{
if(judge(t))//如果解析正確
{
loadFile.setKey(t[0]);
loadFile.setUserName(abc[0]);
loadFile.setReason(abc[1]);
loadFile.setFileName(abc[2]);
loadFile.setIp(t[2]);
}
return (T) loadFile;
}
/**
* 判斷解析是否正確
*/
public boolean judge(String[]t)
{
if(CommondTools.firtstPrevention(t,firstPreventionCount))//第一次解析正確
{
abc=CommondTools.ridOfSpace(t[1]);//得到第二次解析的字符串集
if(CommondTools.secondPrevention(abc,secondPreventionCount))//第二次解析正確表明數據有效
{
return true;
}
}
return false;
}
}
}
</span>
<span style="font-size:18px;">package com.zsj.test.daos;
import java.util.Iterator;
import java.util.Vector;
import com.zsj.test.beans.UdpConnection;
import com.zsj.test.interfaces.InsideClass;
import com.zsj.test.interfaces.StatHandler;
import com.zsj.test.tools.CommondTools;
public class UdpconnectStatHandler implements StatHandler<String[]>{
private int sucessCount=0;//udp連接成功的次數
private int failedCount=0;//udp連接失敗的次數
private final String success="Udp_Connect";
private final String failed="udp連接失敗";
private Vector<String>failedIP=new Vector<String>();//udp連接失敗的IP的集合
@Override
public void output() {
// TODO Auto-generated method stub
System.out.println("UDP connnect stat:");
System.out.println("udp連接成功的次數:" + sucessCount);
System.out.println("udp連接失敗的次數:" + failedCount);
System.out.println("-------------------------------------------");
System.out.println("udp連接失敗的IP的集合:");
Iterator<String> iter = failedIP.iterator();
while (iter.hasNext()) {
String next=(String) iter.next();
System.out.println("IP爲:" +next);
}
System.out.println("----------------------------------------------");
}
@Override
public synchronized void input(String[] t)
{
try
{
getUdpconnect getUdpconnect =new getUdpconnect();
UdpConnection udpConnection=getUdpconnect.getObject(t);
if(udpConnection!=null)
{
if(udpConnection.getFlag()!=null&&udpConnection.getFlag().equals(success))
{
sucessCount++;
}
else
if(udpConnection.getFlag()!=null&&udpConnection.getFlag().equals(failed))
{
failedCount++;
if(!failedIP.contains(udpConnection.getIp()))
{
failedIP.add(udpConnection.getIp());
}
}
}
}catch(Exception e)
{
e.printStackTrace();
}
}
private class getUdpconnect implements InsideClass
{
private String[]abc=null;//解析第二位得到的字符集合
private final int secondPreventionCount=3;//第二次解析得到數據,正確爲6位
private final int firstPreventionCount=4;//第一次解析得到的數據,正確爲4位
private UdpConnection udpConnection=new UdpConnection();
@SuppressWarnings("unchecked")
@Override
public UdpConnection getObject(String[]t)
{
// TODO Auto-generated method stub
if(judge(t))
{
udpConnection.setKey(t[0]);
udpConnection.setUserName(abc[0]);
udpConnection.setFlag(abc[1]);
udpConnection.setExplain(abc[2]);
udpConnection.setIp(t[2]);
}
return udpConnection;
}
@Override
public boolean judge(String[]t) {
// TODO Auto-generated method stub
if(CommondTools.firtstPrevention(t,firstPreventionCount))//第一次解析正確
{
abc=CommondTools.ridOfSpace(t[1]);
if(CommondTools.secondPrevention(abc,secondPreventionCount))//第二次解析正確
{
return true;
}
}
return false;
}
}
}
</span>
有了工具類之後,下一篇回過頭來講第二篇文章中,如何在Allstathandler中獲取對應的工具類,已經如何增強擴展性