程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java咖啡館(9)——一個壓縮歸檔實用軟件

Java咖啡館(9)——一個壓縮歸檔實用軟件

編輯:JAVA編程入門知識
優秀的創意造就實用的工具。借助Java內置強大的API,即使是Java的初學者,只要善於調兵遣將,也能夠成為力拔山兮氣蓋世的霸王!

先睹為快

在病毒肆虐以及BT下載流行的年代,按時備份是一個好習慣。一般而言,只有滿足下列這些蠻橫需求的軟件,才稱得上是一個得心應手的好工具:

★需要備份的文件可能分布在硬盤的各個角落;
★文件名可能比較復雜,不是用DOS的通配符就能夠描述清楚的 ;
★按照文件的時間、大小、類型(文件或者目錄)、最後修改時間等進行篩選;
★能夠把這些文件壓縮,並添加適當的注釋幫助辨認 ;
★能夠添加校驗值以確保復制和網絡傳輸時不出錯;
★保持備份時的目錄結構以便恢復;
★最好能夠同時在多個平台運行;

這樣的軟件存在嗎?沒錯,這就是我們這回咖啡館的主題,我們將綜合運用所學的知識,編寫一個這樣的實用軟件—ExpZip。

首先介紹一下軟件的使用方法。由於Java咖啡館開館以來才短短幾期,還未介紹到GUI(圖形用戶界面)的設計,所以它仍然是一個命令行工具。舉個實際例子,對於Java愛好者而言,自己編寫的程序再重要不過了,這是N個小時的心血啊,自然應該經常備份,世界上沒有後悔藥賣的。打開“命令提示符”窗口,進入項目所在文件夾,輸入:

java ExpZip "C:Documents and SettingsGary Chanworkspace" "[a-zA-Z_$][w$]*.java"

其中java是Java解釋器,ExpZip就是我們將要編寫的Java類編譯以後的class文件。第一個參數代表目標文件夾,第二個參數代表目標文件文件名的表達式,具體含義請看後文詳述。回車以後,Eclipse工作區文件夾中包括所有子文件夾中的所有Java源程序都已經備份到Backup.zip中了。可以用WinRAR打開這個ZIP包。

可以看到,這個壓縮包保留了文件的路徑信息,並且還有注釋,記載著當時的壓縮信息。而且,這是一個Java程序,理論上拿到MacOS上運行都是沒有問題的。

總之,這是一個非常強大的軟件,而且,我們已經有足夠的知識來編寫這個軟件了。不再贅述,先新建一個項目。

Java文件操作

1.File類

Java中是通過File類來存取文件和路徑的。沒錯,這是一個非常容易混淆的名字,你可能認為它僅僅能夠處理文件,實際上它既可以代表了一個特定的文件,又可以代表某個文件夾內的文件名列表。如果它是文件,你可以通過length()方法獲取它的大小、通過lastModified()方法最後修改時間,等等;如果它代表文件名列表,則可以用list()得到表示文件名列表的字符串數組,或者用listFiles()方法得到表示子文件列表的File數組。總之,在Java中文件夾和文件已經被統一成一個抽象的概念,只要了解它的原理,使用起來將會感到非常方便。

2.文件過濾

我們說過,File類的listFiles()方法可以得到表示子文件列表的File數組,如果僅僅想要得到特定的子文件而過濾掉其他的文件,則可以給listFiles()方法加上參數——一個過濾器。
所謂的過濾器,就是一個實現FilenameFilter接口的Java類。所謂接口(interface),就是僅僅定義了行為協議,所有聲明實現這個接口的類必須具體實現這個接口的行為。換句話說,接口是一種契約,比如這裡FilenameFilter的定義是這樣子的:

public interface FilenameFilter {
boolean accept(File dir, String name);
}

我們要得到某個File類的所有子文件夾,過濾器FolderFilter類可以這麼寫:

class FolderFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return new File(dir + "\" + name).isDirectory();
}
}

你看,FolderFilter類通過implements表示對FilenameFilter接口的支持,然後實現了這個接口的accept方法。具體地,在accept方法中,通過傳入的dir參數和name參數新建一個File實例,然後通過調用isDirectory()方法判斷這個實例是否是文件夾,是則返回True,否則返回False。

注意到這個方法必須和FilenameFilter接口裡面聲明的一模一樣。正因為如此,每次手動輸入接口聲明既麻煩又容易出錯。還是讓Eclipse干體力活吧!打開Eclipse,新建一個類,名字為FolderFilter,按下Interfaces文本列表右邊的Add按鈕,在彈出的對話框中輸入FilenameFilter即可。實際上,Eclipse會根據你的輸入進行篩選,非常聰明(見圖1)。

\


別忘記只在Inherited abstract methods前面打勾。最後按下Finish,FolderFilter便創建好了,請根據上文補足代碼。

假設path是一個File類的實例,我們便可以通過File[] subFolders = path.listFiles(new FolderFilter())得到path的子文件夾列表了。

這就是接口的使用。加上前兩次我們講解的Java語言中關於封裝、繼承和多態的知識,Java面向對象編程就基本講完了。

3.過濾器原理

或許你會覺得過濾文件夾還要手動編寫一個類,實在是太麻煩了。實則不然。
給listFiles()參數提供一個實現FilenameFilter接口的類的實例,惟一目的就是讓listFiles()反過來調用作為參數的實例的accept方法。仔細體會一下這句繞口令,真是意味深長啊。這意味著你可以把任何實現FilenameFilter接口的類的實例當作參數傳遞,甚至是在運行時動態改變,從而使得程序更加靈活。而且,如果你要加入更多的過濾器,寫額外的類就可以了,完全不需要修改原先的過濾器,這種動態策略的思想就是一種Strategy模式的體現。

黃糖故事

設計模式(Design Patterns)

建築工程師Cristopher Alexander總結了建築中的經驗教訓,發現有些問題總是一遍又一遍重復出現,當你總結出一套解決這種問題的核心方法以後,你只要放心使用這種解決方法即可,而完全不必再動腦筋想其他的方案。雖然這句話很樸素,但是卻成了軟件工程中一種舉足輕重的方法學—設計模式的指導思想。

我們知道,建築學有牛頓力學作為辯證的理論根據,只要尊重科學,就不可能設計出坍塌的建築(即使坍塌,也是材料施工不過關或其他因素造成的)。但是,編寫軟件卻沒有這樣的理論根據,因為程序只是告訴計算機語法,計算機只要如此這般依計而行,愚忠而已,而沒有機制能保證程序的語意符合人類的思想。因此,程序才會有BUG,即使比爾對Windows XP大吼:“我以老祖宗的名義不准你有BUG!”,Windows XP能夠領會精神嗎?

雖然沒有徹底的解決方法,Erich Gamma等四位大師級的計算機科學家通過借鑒建築學中的模式的概念,創造出軟件中的設計模式,通過精心萃取的23個模式,有效解決了軟件的設計問題,給程序加上了一定程度的模型語意。具體的,請閱讀這“四人幫”(Gang of Four)編寫的《Design Patterns》一書。值得一提的是,我們上一回編寫的名字解析器就是運用了其中的Factory模式,結構非常漂亮。

順便說一句,現在支持設計模式的工具也越來越多 ,如果你想有朝一日從Java程序員升級為呼風喚雨的Java構架師,這可是一門必修課哦!

4.正則表達式(Regular Expression)

說起正則表達式,即使不熟悉,你也會覺得非常眼熟。沒錯,現在的文本編輯軟件,無論是UltraEdit還是EditPlus,無一不支持正則表達式。可以說,不支持正則表達式的編輯器肯定是三流貨色啦。

理論上,正則表達式等價於有限自動機,能夠表達相當豐富的語言,DOS中通配符的能力是無法望其項背的。學過編譯原理或者計算機理論的朋友一定很熟悉了,可是,如果從頭開講,恐怕這期所有版面都不夠。因此這裡推薦你參考Sun免費的Java Tutorial中的Regular Expressions一章,寫得很詳細。即使你熟悉計算機理論的正則表達式,也建議抽空看一看,因為Java采取的是類Perl風格的語法,和理論書上有些出入。

比如我們要過濾出所有Java源程序。眾所周知,Java文件名必須以字母、美元符號或者下劃線開頭,然後可以由數字、字母、美元符號或者下劃線的任意組合,最後擴展名是java。用正則表達式寫出來,就是“[a-zA-Z_$][a-zA-Z_$0-9]*.java”(不含引號)。

其中,[a-zA-Z_$]表示小寫字母a至z、大寫字母A至Z、美元符號或者下劃線任取其一;[a-zA-Z_$0-9]*表示小寫字母a至z、大寫字母A至Z、美元符號、下劃線以及0至9這十個數字的任意組合;“.java”表示Java源程序的擴展名,由於“.”在Java正則表達式中有特殊意義,所以“.”才表示一個“.”符號。

當然,Java正則表達式API中還有許多擴充,可以簡寫為:[a-zA-Z_$][w$]*.java。

有了這些知識,我們不難寫出支持正則表達式的文件過濾器FileFilter,源代碼如下:

public class FileFilter implements FilenameFilter {
private Pattern pattern;

public FileFilter(String regex) {
pattern = Pattern.compile(regex);
}

public boolean accept(File dir, String name) {
File file = new File(dir + "\" + name);
return pattern.matcher(file.getName()).matches() && file.isFile();
}

}

Java中通過Pattern類來使用正則表達式。在FileFilter的構造函數中,通過把regex參數傳遞給Pattern的compi

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved