單線程解析文件,根據文件關鍵詞進行統計,並將結果輸出(三)

上一篇是:單線程解析文件,根據文件關鍵詞進行統計,並將結果輸出(二)

完成了獲取文件輸入,並將每一行分發到對應的處理器的工具類,本次完成對應的三個工具類的實現。

一、首先實現三個需要解析的文件的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中獲取對應的工具類,已經如何增強擴展性
發佈了45 篇原創文章 · 獲贊 12 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章