java 中引入 File 類的目的就是為了將一個外部文件系統(tǒng)中的存儲數(shù)據(jù)的文件和 Java 語言中的 File 類做關(guān)聯(lián),做映射。用這個 File 類去抽象代表文件系統(tǒng)中的文件,這才使得程序有能力通過這個 File 類去操作文件,而且在 java 中文件目錄也會被當做一個 File 類去處理。計算機科學(xué)中最重要的思想就是抽象思想了吧!
File 類常用方法
和文件名相關(guān)
-
public String getName()//取得文件或者目錄的名字 -
public String getPath()//取得文件或者目錄的當前路徑 -
public String getAbsolutePath()//取得文件或者目錄的在文件系統(tǒng)中的絕對路徑
文件檢測
-
public public boolean exists()//判斷文件或目錄是否存在 -
public boolean canWrite()//判斷文件是否可寫 -
public boolean canRead()//判斷文件是否可讀 -
public boolean isFile()//判斷File對象是否代表文件 -
public boolean isDirectory()//判斷File對象是否代表目錄 -
public boolean isAbsolute()//判斷File對象代表文件或目錄是否是絕對路徑名表示
通過文件檢測中的public boolean isFile()和public boolean isDirectory()兩個方法也證明了,Java 語言中是把文件和目錄都用 File 類去抽象表示的。而且這兩個方法的存在同時也證明了,在使用指定的路徑構(gòu)造 File 對象的時候,即便給的是個莫名其妙的路徑,文件系統(tǒng)中根本不存在的路徑,同樣是可以構(gòu)造對象,畢竟其構(gòu)造方法中僅僅接收一個 String 類型的參數(shù)。理解這一點非常重要,因為在實際編程中用到 File 類的時候,很可能會因為路徑不對,沒有構(gòu)造出正確的 File 對象,而導(dǎo)致程序出現(xiàn)問題。
這里也有一個做筆記的啟示,根據(jù)后續(xù)的理解,回頭找到原先的筆記,進行擴展和補充。如果不回頭來做記錄,那么好不容易得出的感悟,過段時間,一定會遺忘,也就無法將新的感悟,變成自己的基本功了。只有不斷累積自己的基本功,水平才能提升。
File 類的兩個重載方法
public String[] list()和public String[] list(FilenameFilter filter),這兩個重載方法的功能就是列舉出該目錄下的所有文件名(Java 中目錄也被當做是一個文件處理),用一個 String[] 類型的數(shù)據(jù)封裝起來作為方法返回值返回。
第二個方法public String[] list(FilenameFilter filter)不同于第一個方法的地方在于,可以對目錄下的文件進行過濾。具體實現(xiàn)方式是接收一個 FilenameFilter 接口類型的參數(shù),進行過濾。
FilenameFilter 接口源碼如下,可見這是 java.io 中專門設(shè)計來對文件名進行過濾的一個接口,它有一個唯一的抽象方法boolean accept(File dir,String name),通過這個方法來實現(xiàn)文件過濾的功能。其中第一個參數(shù) dir 接收的是調(diào)用 list(FilenameFilter filter) 方法的對象 this 指針(也就是需要進行文件名過濾的的文件的父目錄),第二個參數(shù) name 是需要進行過濾的文件名。這兩者組合起來才是完整的文件路徑啊,所以需要調(diào)用 File 類的public File(String parent,String child)構(gòu)造函數(shù)對生成的 File 類對象進行初始化。
package java.io;
public interface FilenameFilter {
boolean accept(File dir, String name);
}
那么public String[] list(FilenameFilter filter)方法是如何實現(xiàn)的呢?源碼如下,可見此方法內(nèi)部是先調(diào)用了 list() 方法得到該目錄下的所有文件名組成的字符串數(shù)組對象,然后通過 filter 接口變量調(diào)用它的 accept() 方法進行判斷是否符合過濾規(guī)則。如果符合就添加到 ArrayList 容器中,直至所有的文件名都判斷完后,就轉(zhuǎn)成一個字符串數(shù)組對象返回。
public String[] list(FilenameFilter filter) {
String names[] = list();
if ((names == null) || (filter == null)) {
return names;
}
List<String> v = new ArrayList<>();
for (int i = 0 ; i < names.length ; i++) {
if (filter.accept(this, names[i])) {
v.add(names[i]);
}
}
return v.toArray(new String[v.size()]);
}
那么如何使用這兩個重載方法?
對于public String[] list()方法,直接用一個目錄 File 對象調(diào)用它即可。
對于public String[] list(FilenameFilter filter)對象,首先要新建一個類實現(xiàn) FilenameFilter 接口,重寫 accept() 方法,指定過濾規(guī)則。然后將這個對象的引用作為參數(shù)傳遞給 list() 方法。這個過程就叫做回調(diào)模式!
什么叫做回調(diào)函數(shù)?
上面提到的public String[] list(FilenameFilter filter)方法就是回調(diào)方法。到底什么叫做回調(diào)呢?比如這里 File 類提供的這個方法接受一個 FilenameFilter 接口類型的參數(shù),該方法內(nèi)部會調(diào)用該接口的 accept() 方法。但使用這個方法的前提是自定義一個類實現(xiàn)該接口,實現(xiàn)它的抽象方法。并將給類的對象作為參數(shù)傳遞給 list() 方法的過程就叫做回調(diào)。
抽象點的說法就是:程序員A定義了一個方法,該方法接受一個指定接口類型的參數(shù)對象,并會在該方法內(nèi)部調(diào)用該接口的某個抽象方法。然后程序員B 則定義了一個類實現(xiàn)該接口,并重寫該抽象方法,然后將對象作為參數(shù)傳遞給程序員A定義的方法,由程序員A的方法來回調(diào)程序員B重寫的方法,這就叫做回調(diào)。