?? 6.+
字號:
軟件源代碼清單
*由于源代碼太長,這里只貼出核心搜索線程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 + -