摘 要
計算機技術給我們的日常生活帶來了很多便利
來自生產線 的產品
高效的通信以及大量易於訪問的信息
然而它同時也帶來了垃圾電子郵件
幸運的是
我們已經有辦法對付它
本文將對Java類庫的I/O包以及建立在其上的
流
模型進行深入的討 論
包括
它是如何工作的
Java
和Java
在I/O實現方面的差別
以及如何利用這些知 識建立一個垃圾電子郵件
過濾器
足不出戶
也能至富
神奇的飲食
一周減肥
磅
熱情的XXX寶貝想見你
有時
我們會收到很多不受歡迎的 電子郵件
這些郵件往往令人不快
那些還沒有受垃圾電子郵件之苦的幸運者也應該意識到這 是一個現實的問題
這裡我們將介紹一種利用JAVA控制垃圾電子郵件的方法
監視敵人
我們無法逃避垃圾電子郵件
只能 盡量減少它對我們生活的侵擾
最好
也是最有效的方法是阻止人們給我們發不受歡迎的電子 郵件
我們必須在看到垃圾電子郵件之前消除它
那麼如何實現呢?
一種行之有效的方法是檢查電子郵件的內容
然後決定是否保留它
其實
我們在閱讀電子郵件時就是這樣做的
我們一個接一個字符
一行接一行地讀電子郵件
搜索我們認識地單詞
如果其中包括單詞
Java
我們便保留它
如果包括
MakeMoneyFast
我們便將它扔到垃圾桶裡
能否編制一個計算機程序來幫助我們更有效地工作呢?
戰術評估
下面
我們討論Java類庫I/O包中 的類
Java類庫的輸入輸出類基於一種簡單但強大的模型
流
(Streams)
在
流
模型中
信 息從一點
流
到另一點
就象在河流或者管道中一樣
在
流
中的任何一點
觀察者看到信息一 點一點地順序流過
這種模型適合現實世界中很多類型的信息
比如來自計算機鍵盤的鍵 碼(Keycodes)
來自聲音文件的聲音數據
來自文本文件的一行接一行的文本等都是信息流
圖
流
中信息從一點傳到另一點
流
中的一個重 要工具便是
過濾器
(Filters)
過濾器
從
流
的
上游
獲取信息
用某種方式過濾或者處理 後
發送到
流
的
下游
流
模型功能強大的關鍵是可以用一些非常簡單的
獨立的
過濾器
串成一個功能強大的復合
過濾器
圖
過濾器
中斷處理信息流
圖
級聯
過濾器
Java類庫將
流
分為兩類──輸 入和輸出
這種區分在理論上是不必要的
但是在實際應用中卻是有用的
輸入
流
的最初來源 是某一設備或者文件
它將數據從設備或文件輸入到程序中
輸入
流
在處理中一般是要過濾 的
輸出
流
的最終目標也是某一設備或者文件
它將數據從程序輸出到設備或文件中
輸入
流
在處理中一般也是要過濾的
有兩個原因使我們將Java類庫中 的
流
類應用到垃圾電子郵件問題的解決方案中
可以很容易地將電子郵件看做是一個接一個字符
一行接一行進入到計算機的
當電子郵件進入計算機時
我們要一個接一個字符
一行接一行地檢查是否與我們指定的模板匹配
兵工廠──
流
類詳細介紹
Java
說明書中描述了兩種基 本相同的輸入和輸出類集
一種是面向字節的
另一種是面向字符的
面向字節
流
類與在Java
中實現的只有微小的差別
而面向字符
流
類是在Java
版本中最新實現的
本文中我們討論面向字節的
流
類
這樣做有兩個原因
首先
對那些沒有使用Java
的人也可以利用這份材料
其次
我們可以指出Java
中類庫中出現
在Java
中已經修正的一些錯誤
上面已經提過
流
可以分為兩類
輸入
流
和輸出
流
在Java中
所有面向字節的輸入
流
類都是抽象類InputStream的子類
InputStream定義了所有輸入
流
類必須提供的一套基本方法(Mothods)
同樣
所有面向字節的輸出
流
類都是抽象類OutputStream的子類
OutputStream定義了所有輸出
流
類必須提供的一套基本方法(Mothods)
通用輸入
流
類方法
以下是對所有輸入
流
通用的方 法
每個方法說明之後列出了方法能執行的任務
publicint read()throws IOException
從輸入
流
讀一個 字節並且返回此字節
如果已經 到了輸入
流
的結尾
則返回
如果必要
阻塞(或等待)直到數據可用
當讀操作時發生錯誤
則拋 出IOException異常
publicint read(byte[]rgb) throws IOException
從輸入
流
讀一字節序列並且置於指定的數組中
返回所讀的字節數
如果已經到了輸入
流
的結尾
則返回
如果必要
阻塞(或等 待)直到數據可用
當讀操作時發 生錯誤
則拋出IOException異常
publicint read(byte[]rgb
intnOff
intnLen)throws IOException
從輸入
流
讀一指定長度的字節 序列並且置於指定的數組中指定偏移上
返回所讀的字節數
如果已經到了輸入
流
的結尾
則返回
如果必要
阻塞(或等 待)直到數據可用
當讀操作時發 生錯誤
則拋出IOException異常
publiclong skip(longn) throws IOException
跳過指定 的字節數
返回跳過的字節數
如果已經到了輸入
流
的結尾
則返回
當操作時發生錯誤
則 拋出IOException異常
publicinta vailable() throws IOException
返回可以 從輸入
流
中讀取的字節數
而不產生讀操作阻塞
當操作時發生錯誤
則拋 出IOException異常
publicvoid close()throws IOException
關閉輸入
流
釋 放所有與此輸入
流
有關的資源(例如操作系統文件句柄)
當操作時發生錯誤
則拋 出IOException異常
publicvoid mark(int nReadLimit)
在輸入
流
中標識 當前位置
以後當調用reset()時
輸入
流
將重新定位在此位置上
指定在標識無效之前
標識之後 能讀取的字節數
publicvoid reset()throws IOException
將輸入
流
重新定 位在最近標識的位置上
如果
流
沒有標識
或者標識已經無效
則拋出IOException異常
public boolean mark Supported()
顯示此輸入
流
是否支持mark和reset操作
通用輸出
流
類方法
以下是對所有輸出
流
通用的方 法
與前一部分一樣
每個方法說明之後列出了方法能執行的任務
publicvoid write(byteb) throws IOException
將一個字 節寫入輸出
流
阻塞(或等待) 直到數據真正寫入
當寫操作時 發生錯誤
則拋出IOException異常
publicvoid write(byte[] rgb)throws IOException
將一 個字節序列寫入輸出
流
阻塞( 或等待)直到數據真正寫入
當寫操作時發生錯誤
則拋出IOException異常
publicvoid write (byte[] rgb
intnOff
intnLen) throws IOException
將一個指定長度的字節序列從指 定的偏移量開始寫入輸出
流
阻塞(或等待)直到數據真正寫入
當寫操作時發生錯誤
則拋 出IOException異常
publicvoid flush ()throws IOException
沖洗
輸出
流
立即寫所有的緩沖數據
當操作 時發生錯誤
則拋出IOException異常
publicvoidclose()throws IOException
關閉輸出
流
釋 放所有與此輸出
流
有關的資源(例如操作系統文件句柄)
當操作時發生錯誤
則拋 出IOException異常
攻擊計劃
本文的代碼有三種形式
這是因 為
在Java
中字節到字符的轉換有重要的瑕疵(使語言對Unicode的支持無實質用處)
為 了支持國際化
這個瑕疵在Java
中得到了修正
結果是產生兩套幾乎相同的API
僅僅在提 供給字節到字符的轉換的方法有所區別
為了給所有人提供可工作的代碼
以及顯示API是如何 改變的
我們用三個包提供代碼
必要時可以下載所有三個包做比較
也可以下載適合你平台的 包
第一個包運行在Java
有tar文件和zip文件
第二個包運行在Java
也 有tar文件和zip文件
第三個包同時運行在Java
和Java
這個包沒有使用API中沖突的部分
它自己完成工作
你如果對可移植性更感興趣
可以以tar文件或者zip文件下載此包
本文的代碼不是以小程序(Applets)的方式運行
所以你 需要Java Develop ment Kit或者類似的命令行環境
首先在你的系統中用正確的方 法解開下載的文件
然後在命令行下按照如下命令執行Java Runtime
%javaMain [keyword] [keyword]...[emailfile]
你可以在命令行中指定任意多的關鍵字(Keywords)
程 序對每個關鍵字建立一個
過濾器
然後將它們一起連接入一個
流
當輸入以標准輸入 進入時
程序從標准輸入中讀取數據
通過
流
傳送這些數據
寫入標准輸出中
如果有一 個
過濾器
檢測到一個關鍵字
就會產生一個異常
以結束程序
這種解決方案很簡單
但 是非常有用而且高效
From:http://tw.wingwit.com/Article/program/Java/Javascript/201311/25282.html