[瘋狂Java]I/O:File(檔案類,也是檔案流的節點)、FilenameFilter(檔案過濾器)
1. Java的File類簡介:
1) java.io包下的代表與平臺無關的檔案和目錄;
2) File本身只能完成對磁碟上檔案和目錄的新建、刪除、重新命名等操作(即只能修改檔案屬性,但不能修改檔案中的內容);
3) 也就是說File物件只是一個儲存節點,想要修改、訪問檔案中的內容,必須在File節點上建立檔案節點流才行,必須通過流才能修改訪問檔案中的內容!
4) File底層必定是和平臺相關,各個平臺(作業系統)的檔案系統實現不盡相同,必然包含具體的平臺驅動,只不過虛擬機器在應用層面上隱藏了這一差異;
!!以下介紹的都是File類的物件方法;
2. 檔名相關方法:檔案、目錄通用
1) 首先File的構造器就要指定一個檔案路徑名:File(String pathname);
2) File中有一個數據成員String path,構造後就會用pathname引數來對path賦值;
3) 例如:File f = new File("dir\\test"); // 在Windows中路徑分隔符是反斜槓,因此在字串常量中需要轉義
!!這裡就會把字串dir\test存入path中;
4) 獲取檔名:String getName(); // 這裡返回的就是test,即path變數中去掉路徑部分
5) 獲取完整的路徑名:String getPath(); // 這裡返回的就是dir\test,即path的完整值
6) 獲取絕對路徑名:String getAbsolutePath(); // 這裡返回的諸如D:\doc\eclipse\Test\dir\test的絕對與路徑
!!即"環境路徑\path",其中環境路徑就是new File時執行該JVM時的路徑
7) 獲取父目錄:String getParent(); // 這裡返回的就是dir,如果建立File是傳入的路徑是xxx\dir\test,那這裡返回的就是xxx\dir,即path中去掉字尾檔名的結果
8) 獲得絕對路徑包裝的File物件:File getAbsoluteFile(); // 返回的File物件中的path的值等於getAbsoluePath的返回值,即用絕對路徑來裝填path成員變數,得到一個新的File物件
!!可以看到,以上檔名的相關方法都是純粹的對path這個字串變數進行解析而已,並不會真正到檔案系統中檢查該路徑指定的檔案是否存在,僅僅是一種字串層面上的解析而已!!!
!!即使給定的檔案不存在也可以正常呼叫這些方法並返回相應的結果;
9) 修改檔名:renameTo方法,但該方法支援的並不好,各平臺之間差異較大,並且有些平臺上並不支援,因此這裡就不做介紹了;
3. 屬性檢測:檔案、目錄通用
1) 是否存在:boolean exists();
2) 可讀:boolean canRead();
3) 可寫:boolean canWrite();
4) 是否是目錄:boolean isDirectory();
5) 是否是檔案:boolean isFile();
6) 檢測path成員變數的內容是否是絕對路徑:boolean isAbsolute();
4. 檔案常規屬性:只適用於檔案
1) 最後修改時間:long lastModified();
2) 檔案大小(位元組):long length();
5. 建立、刪除:是適用於檔案
1) 新建檔案:boolean createNewFile(); // 按照成員變數path的名稱新建一個檔案,必須是原檔案不存在的情況下才能新建,否則將新建失敗(而不會覆蓋原檔案)而返回false
2) 刪除檔案:boolean delete(); // 刪除成員path所代表的檔案,如果指定的路徑不存在將失敗返回false
3) 建立臨時檔案:static File createTempFile(String prefix, String suffix, File directory);
i. 以directory+prefix+隨機數+suffix作為檔名(裝載到path成員變數中)在指定目錄directory下建立一個檔案;
ii. 正因為是臨時,因此中間用隨機數作檔名;
iii. 例如:File tmp = File.createTempFile("mail", ".tmp", new File("dir")); // 得到的檔案tmp的path變數值為dir\mailXXXXXXX.tmp,並且在dir目錄下建立了一個該檔案
!!prefix要求至少三個字元,而suffix可以為null;
!!這是File類的靜態方法,也就是工具方法!
4) 一般臨時檔案都是在程式中臨時使用的,都希望能在程式退出時就自動刪除這些臨時檔案:void deleteOnExit(); // 註冊了一個刪除鉤,表示在程式結束時自動刪除該檔案
!!該方法只要是File物件都能呼叫,不一定是臨時檔案;
!!其實臨時檔案也是普通檔案,只不過其名字中有隨機生成的數字而已;
6. 目錄操作:只適用於目錄
1) 建立單個目錄:boolean mkdir(); // 以path指定的名字在當前目錄下建立一個目錄,必須是原來不存在的,否則會false失敗返回
!!該方法不能巢狀建立,比如dir1\dir2這樣是不能建立,只能建立單個目錄,比如dir1
2) 巢狀建立:boolean mkdirs(); // 以path指定的名字巢狀建立多級目錄,同樣必須是原來不存在的,否則會false失敗返回
!!只要path路徑中有一級不存在就可以成功建立,比如dir1\dir2\dir3,dir1已經存在了,但是dir2不存在,那麼同樣可以成功創建出dir1\dir2\dir3多級目錄
3) 返回目錄下所有檔案(包括子目錄)的名稱:String[] list();
4) 返回File物件:File[] listFiles();
5) 利用靜態方法listRoots獲得作業系統的所有根目錄:static File[] listRoots();
!!返回的各個File物件的path值例如:C:\、D:\等,因此呼叫getName方法得到的是空,之後呼叫getPath或者getAbsolutePath才能得到真正的路徑名,其實就是一個碟符;
!!在Windows中是這樣的,如果在Unix/Linux中,返回的是所有掛載到作業系統上的磁碟名稱了!!
7. 檔案過濾器:
1) 可以看到在使用list和listFiles方法列出目錄中的檔案(和目錄)時還有第二個版本的過載,即需要一個FilenameFilter的過濾器;
2) 過載版本:
i. String[] list(FilenameFilter filter);
ii. File[] listFiles(FilenameFilter filter);
!!即可以通過過濾器來過濾出你想要的檔案;
3) FilenameFilter是一個函式式介面,裡面只有一個方法需要實現,就是:boolean accept(File dir, String name);
i. name是待檢查的檔案的名字,dir是該檔案所在的目錄;
ii. 在呼叫list和listFiles時會將目標目錄下的所有檔案和目錄用accept試一下,如果能接受就過濾出來並返回;
iii. 因此需要實現accept方法來自定義過濾哪些檔案;
4) 示例:
dir.list((dir, name) -> name.endsWith(".txt") || new File(name).isDirectory());
!即我們想要的是.txt檔案或者子目錄都行;
!!由於是函式式介面,可以使用Lambda表示式;