⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 6.+

📁 jSearch - turns search Engines into FIND engines - Programming in JAVA Copyright (C) 1999-2009 Hun
💻 +
字号:
软件源代码清单

*由于源代码太长,这里只贴出核心搜索线程SearchThread的源代码,其它代码请参看:JSApplet.java和SearchThread.java

SearchThread.java
/*
 *   JSearch - turns search Engines into FIND engines - Programming in JAVA
 *   Copyright (C) 1999-2002  Hunt Lin
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *   Also add information on how to contact you by electronic and paper mail.
 */
 
import java.io.*;
import java.net.*;

public class SearchThread extends Thread {

	//要搜索的内容
	String srchChainConverted;
	//当前搜索线程的序号
	int srchNo;
	//搜索引擎的基本信息
	String srchBlkB, srchBlkE, srchEngName;
	
	//定义搜索当中要用到的变量
	String srchChainConvertedWithLevel;			//加入Level后的搜索串
	BufferedReader inURLStream;					
	char matchChars[]	= {' ', ' ', ' ', ' '};	//将与标志相符的字符
	char singleChar[]	= {' '};				//每次取得的字符
	String matchString;							//用作matchChars到String的转化。
	int resultCount		= 0;					//当前线程找到的结果

	//准备搜集的信息
	String			resultDtlHead	= new String();			//用于存放结果集中的URL
	ResultsDetails	resultDtlBody	= new ResultsDetails();	//用于存放主题和预览
	
	//核心搜索线程
	public void run() {
		try {
			for (int level=0; level < Integer.valueOf(JSApplet.smlCh.getSelectedItem()).intValue() && !JSApplet._stop; level++) {
				
				//用级数处理搜索串
				srchChainConvertedWithLevel = srchChainConverted.replace('`',(char)(48+level));
				//打开搜索的页面流
				inURLStream = new BufferedReader(new InputStreamReader((new URL(srchChainConvertedWithLevel)).openStream()));
				//推进
				while (stepOneChar()) {
					//找到信息块的开始:srchBlkB
					if (matchString.equals(srchBlkB)) {
						
						//准备收集信息
 						resultDtlHead = "";
						resultDtlBody.title = "";
						resultDtlBody.preview = "";

						//对信息块进行分析,并取出URL,TITLE,PREVIEW
						analyseBlock();
						
						//将最后一个非结果集排除,因为最后一个信息块的结束不可能也是页面的结束。或如果当页已结束则退出。
						if (!stepOneChar()) break;
						
						//适当休眠,让PREVIEW有办法进行!且让其它搜索线程有办法进行!并让死锁有时间释放。并且如果有多个线程,这0.1秒的重叠后也就不算什么了。
						Thread.sleep(100);
						
						//对所得到的结果进行网址有效性验证
						if (JSApplet.valurlCh.getSelectedItem().equals("Yes")) {
							if (!validUrl()) break;	//如果验证不通过,则不将这个URL记入/显示。
						}

						//将结果存放并显示
						showResult();
						
					} //if
				} //while
				
				//关闭流
				inURLStream.close();
			}
			
		} catch(Exception ex) {
			JSApplet.messageTe.append("Exception: '" + ex.toString() + "' in SearchThread.run().\n");
		}
		
		//将活动连接减一,并适时地置按钮的状态。
		if (--JSApplet.actualSearchAllowed == 0) {
			JSApplet.buttonStatus(2);
			JSApplet._stop = true;
		}
	}
	
	//用传入的变量对类中的变量进行赋值
	public SearchThread(String srchChainConverted, String srchBlkB, String srchBlkE, String srchEngName, int srchNo) {
		this.srchChainConverted	= srchChainConverted;
		this.srchBlkB			= srchBlkB;
		this.srchBlkE			= srchBlkE;
		this.srchEngName		= srchEngName;
		this.srchNo				= srchNo;
	}
	
	//向前推进一个字符
	boolean stepOneChar() {
		boolean _step = false;
		try {
			if (inURLStream.read(singleChar,0,1) != -1 && !JSApplet._stop) {
				matchChars[0]	= matchChars[1]; 
				matchChars[1]	= matchChars[2]; 
				matchChars[2]	= matchChars[3];
				matchChars[3]	= singleChar[0];
				matchString		= new String(matchChars); //不能用toString()!!!
				_step = true;
			}
		} catch(Exception ex) {
			JSApplet.messageTe.append("Exception: '" + ex.toString() + "' in SearchThread.stepOneChar().\n");
		}
		return _step;
	}

	
	//分析信息块
	void analyseBlock() {
		/////取得网址
		//找到网址标志
		while (!matchString.equals("ref=")) {
			if (!stepOneChar()) break;
		};
		//跳过第一个'='
		if (!stepOneChar()) return;
		//处理并得到网址,主要是去掉"\""(引号)
		while (singleChar[0] != '>' && singleChar[0] != ' ') {
			//向前推进一个字符
			if (singleChar[0] != '\"') resultDtlHead += singleChar[0];
			if (!stepOneChar()) break;
		}
						
		//处理由于遇到' '提前退出时,继续处理至'>'
		while (singleChar[0] != '>') {
			//向前推进一个字符
			if (!stepOneChar()) break;
		}
						
		/////取得标题
		//当遇到"</a>"结束。
		while (!matchString.equals("</a>")) {
			if (!stepOneChar()) break;
			//过滤"<"和">"之间的内容。
			if (singleChar[0] == '<') {
				while (singleChar[0] != '>') {
					if (!stepOneChar()) break;
				}
			}
			if (singleChar[0] != '>') resultDtlBody.title += singleChar[0];
		}
						
		/////取得预览
		while (!matchString.equals(srchBlkE)) {
			if (!stepOneChar()) break;
			//过滤"<"和">"之间的内容。
			if (singleChar[0] == '<') {
				while (singleChar[0] != '>') {
					if (!stepOneChar()) break;
				}
			}
			if (singleChar[0] != '>' && singleChar[0] != '\r' && singleChar[0] != '\n') resultDtlBody.preview += singleChar[0];
		}
	}
	
	//网址有效性验证
	boolean validUrl() {
		boolean vldOk = false;
		try {
			(new BufferedReader(new InputStreamReader((new URL(resultDtlHead)).openStream()))).close();
			vldOk = true;
		} catch(Exception ex) {
			JSApplet.messageTe.append("Exception: '" + ex.toString() + "' in SearchThread.validUrl().\n");
		}
		return vldOk;
	}

	//格式化结果集
	String formatString(String unFmtStr, int width) {
		String fmtStr;								//要返回的格式化的字符串。
		byte unFmtBytes[] = unFmtStr.getBytes();	//按byte对unFmtStr进行处理
		if (unFmtBytes.length > width) {
			fmtStr = new String(unFmtBytes, 0, width);
			//处理汉字可能被中间截断的情况。
			if ((fmtStr.equals("")) || (fmtStr.getBytes().length < width)) fmtStr = (new String(unFmtBytes, 0, width-1)) + " ";
		} else {
			String addSpaces = "";	//需要填充的字符。
			for (int i = unFmtBytes.length; i < width; i ++) addSpaces += " ";
			fmtStr = unFmtStr + addSpaces;
		}
		return fmtStr;
	}
	
	//显示结果信息
	void showResult() {
		synchronized (JSApplet.resultTable) {synchronized (JSApplet.resultIndex) {synchronized (JSApplet.resultLi) {synchronized (JSApplet.statusLi) {synchronized (JSApplet.totalNumLa) {
			if (!JSApplet.resultTable.containsKey(resultDtlHead) && !JSApplet.resultIndex.contains(resultDtlHead)) {
				
				//一定要新建一个才能放进HashTable中!
				ResultsDetails resultDtlBody	= new ResultsDetails();
				resultDtlBody.title				= this.resultDtlBody.title;
				resultDtlBody.preview			= this.resultDtlBody.preview;
				
				//将结果放入JSApplet的resultTable/resultIndex中共用。
				JSApplet.resultTable.put(resultDtlHead, resultDtlBody);	//必须要用独立的resultDtlBody对象才能放入HashTable
				JSApplet.resultIndex.addElement(resultDtlHead);
								
				//将结果显示于JSApplet中,要对所得结果用formatString进行必要的格式化。
				JSApplet.resultLi.add(formatString(resultDtlBody.title, 42) + " | " + formatString(resultDtlHead, 40) + " | from: " + srchEngName);
				JSApplet.totalNumLa.setText(String.valueOf(Integer.valueOf(JSApplet.totalNumLa.getText()).intValue() + 1));
								
				//在STATUS中显示当前搜索状况
				JSApplet.statusLi.replaceItem("Results:" + String.valueOf(++resultCount) + " From:" + srchEngName + " Received.", srchNo);
			}
		}}}}}
	}
	
	//析构函数
	public void finalize() throws Throwable {
		try {
			//人工退出,要将inURLStream关闭
			if (this != null) if (inURLStream != null) inURLStream.close();
		} catch (Exception ex) {
			JSApplet.messageTe.append("Exception: '" + ex.toString() + "' in SearchThread.finalize().\n");
		}
		super.finalize();
		System.gc();
		System.runFinalization();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -