Java基礎進階 ?IO介紹之File類、文件過濾器

1、IO介紹

在前期的學習上述知識點的過程中,我們書寫的任何程序,它運行的時候都會有數據的產生,比如時間數據,而這些數據最終都保存在內存中。程序運行結束之后,數據就沒有了。當程序下次啟動的時候,如果還需要使用上次的結果,這時程序中是沒有的。

而在開發中,在我們真正書寫的程序中,往往有一些數據是需要長久保存起來的,當程序中需要這些長久保存起來的數據的時候,再從其他的地方讀取到程序中。

也就是說我們以前學習的數據都是存儲到內存中,而內存中只能暫時存儲數據,當電腦關閉之后,數據就不見了。如果在開發中需要大量數據被長久保存,下次開電腦這些數據仍然還在,那么我們肯定不能保存到內存中,我們需要保存在能夠保存持久數據的地方或者叫持久設備。

那么問題來了:什么是持久設備呢?

1.1什么是持久設備

持久設備:可以持久保存數據的設備。硬盤、U盤、光盤、網盤、軟盤等。這些設備都可以長久的保存數據。
那么還有一個問題:如何把程序中的數據保存到持久設備中?
Java提供了一個技術,專門來實現數據與持久設備間的交互:IO技術。
通過IO技術就可以達到程序和其他設備之間的數據交互。

1.2什么是IO技術

IO技術:它主要的功能就是把我們程序中的數據可以保存到程序以外的其他持久設備中(如:我們電腦的硬盤),或者從其他持久設備中(如:我們電腦的硬盤)進行讀取數據,把數據讀取到我們的Java程序中。
IO:
I:Input:輸入或者讀取,從持久設備(硬盤)的數據放到內存中;
O:Output:輸出或者寫出,從內存中的數據放到持久設備(硬盤)上;

也可以按照如下理解:
把從持久設備(硬盤)上讀取(輸入)到內存中的動作,稱為讀操作。 I:input。
把內存中的數據輸出(寫出)到持久設備(硬盤)的動作,稱為寫操作。O:output。

讀寫操作圖解如下所示:


1.png

說明:
1)我們的程序運行在內存中,因此我們的輸入和寫出都是相對內存而言;
2)Java程序必須運行在Java虛擬機上,Java程序最終需要JVM來執行;
3)JVM屬于應用軟件需要安裝在操作系統軟件上,所以JVM虛擬機是運行在操作系統之上的,然后由操作系統和計算機硬件進行交互;

2、File類

2.1、File類介紹

數據最終保存在硬盤上,在硬盤上是以1和0 保存的。而給我們展示出來的并不是二進制數據,而是一個一個的文件,換句話說數據最終都保存在這些文件中。而這些文件又被文件夾管理。
通過上述描述我們發現在計算機硬盤中就存在兩種事物:文件和文件夾事物。而在Java中使用class類來描述生活中存在的事物,那么Java中是如何描述文件和文件夾這兩類事物呢?

使用File類來描述文件和文件夾事物。


2.png

說明:
1)Java中的定義的io技術的類基本都在java.io包下;
2)使用File類來描述文件和文件夾事物的;
3)File類它主要是對持久設備上的文件和文件夾進行操作。它不能去操作文件中的數據。將來我們只要需要操作持久設備上的文件或文件夾直接找File類完成,如果要操作文件中的數據只能找后面學習的IO技術搞定;

結論:File類就是描述文件或文件夾的,只要我們在Java中要操作文件或文件夾,就找File類。

2.2、File類構造方法

3.png

1)public File(String pathname) 表示根據文件或文件夾的路徑名創建一個File對象。
使用File類的構造函數可以把指定的字符串封裝成File類的對象,但是這個字符串表示的路徑或者文件到底是否存在,File類是不進行判斷的。
注意:File類表示文件和目錄路徑名的抽象表示形式。那么該路徑代表的文件或文件夾不一定存在。

需求:創建一個File類的對象,表示:D:\abc\1.txt


4.png

2)public File(String parent,String child) 根據父目錄的路徑名和兒子的名稱創建一個File對象。

創建是兒子的對象
需求:創建一個File類的對象,表示:D:\abc\1.txt


5.png

3)public File(File parent,String child) 根據父目錄的File對象和兒子的名稱創建一個File對象。
就是把已經存在的File對象和某個子目錄合并成一個新的File對象。
分析和步驟:
A:創建一個File類的對象parent,D:\abc作為參數;
B:定義一個字符串child=1.txt;
C:使用上述構造函數在重新創建一個File類的對象file,并輸出打印;


6.png

2.3、獲取方法

File類是描述文件和文件夾的。使用File類的對象就可以獲取當前File類描述的那個文件或文件夾的信息(信息包括文件或者文件夾的名稱、大小、類型、日期等)。

案例:File類中的獲取方法。
A:getAbsolutePath() 獲取的當前調用這個方法的File對象的全路徑(絕對路徑或者真實路徑) 返回的是路徑的字符串;
B:getAbsoluteFile()獲取的當前調用這個方法的File對象的全路徑(絕對路徑或者真實路徑) 返回的是路徑封裝成的新的File;

說明:在操作文件時,需要指定文件的路徑,而路徑在程序中有兩種表現形式:
1、 絕對路徑(真實路徑):是從盤符開始的路徑,帶有根目錄的路徑 例: D:\abc\test\Demo.java D就是根目錄。
2、 相對路徑:是從當前路徑開始的路徑,或者可以理解不帶根目錄的路徑
例: 當前路徑為D:\abc,要描述相對路徑,只需輸入test\Demo.java
實際上,嚴格的相對路徑寫法應為: .\test\Demo.java
其中,. 表示當前路徑。
C:getName() 獲取的是File類的對象中封裝的文件或目錄的最后一級名稱;
D:getParentFile() 獲取到的是File類的對象的父目錄,把父目錄封裝成一個新的File對象;
E:getParent() 獲取到File類的對象的父目錄,把返回目錄的字符串表示形式;
F:getPath() 獲取到當前File類的對象中封裝的內容;</pre>
G:getFreeSpace() 獲取某個盤的剩余空間;
H:getTotalSpace() 獲取某個盤的總空間;
I:public static File[] listRoots() 獲取系統的所有根目錄,例如:C盤、D盤、E盤、F盤;
說明:由于該函數是靜態的,直接使用類名調用即可。
獲取函數代碼演示如下所示:

package cn.xuexi.file.constructor.demo;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
 * File類中的獲取方法演示
 * 絕對路徑:帶根路徑
 * 相對路徑:不帶根路徑 test\\haha表示相對路徑,這里表示相對于項目day19a來說
 */
public class FileGetFunctionDemo {
    public static void main(String[] args) {
        // 創建File類的對象
        File file=new File("D:\\test\\123.txt");
        //getAbsolutePath()獲取絕對路徑演示 返回的是路徑的字符串 D:\test\123.txt
         //如果File file=new File(""); 參數不指定路徑,則輸出當前項目的路徑F:\newEclipseWorkspace\beike\day19a
        String absolutePath = file.getAbsolutePath();
        System.out.println("absolutePath="+absolutePath);
        //getAbsoluteFile()獲取絕對路徑演示 返回的是路徑新封裝的File類的對象 D:\test\123.txt
         //如果File file=new File(""); 參數不指定路徑,則輸出當前項目的路徑F:\newEclipseWorkspace\beike\day19a
        File absoluteFile = file.getAbsoluteFile();
        System.out.println("absoluteFile="+absoluteFile);
        //getName()函數  獲取的是封裝在File類中的文件或者文件夾的最后一級名稱 123.txt
        System.out.println("getName()="+file.getName());
        //getParentFile()函數演示 獲得File類中的文件或者文件夾的路徑的父目錄 封裝在在一個File類中D:\test
        System.out.println("getParentFile()="+file.getParentFile());
        //getParent()函數演示 獲得File類中的文件或者文件夾的路徑的父目錄 封裝在String類中 D:\test
        System.out.println("getParent()="+file.getParent());
        //getPath()表示獲得File類中封裝的所有內容 D:\test\123.txt
         //如果File file=new File(""); 參數不指定路徑,則輸出””空字符串
        System.out.println("getPath()="+file.getPath());
        //getFreeSpace() 函數
         //如果File file=new File("D:\\"); D盤剩余空間是:366774648832
        System.out.println("剩余空間是"+file.getFreeSpace());
        //getTotalSpace() 函數
         //如果File file=new File("D:\\"); D盤總空間是:371056439296
        System.out.println("總空間是"+file.getTotalSpace());
        System.out.println("----------------");
        //調用listRoots()函數獲取系統的根目錄 由于該函數是靜態的,直接使用類名調用即可
         //  輸出結果C:\ D:\ E:\ F:\ G:\ H:\ 
        File[] dirs = File.listRoots();
        for (File dir : dirs) {
            System.out.print(dir+” ”);
        }
    }
}

J:public long lastModified() 獲取上一次修改的時間,返回的是毫秒值;

演示lastModified函數:
分析和步驟:
1)創建File類的對象file2,D:\test\123.txt作為構造函數的參數;
2)使用對象file2調用lastModified()函數獲得上次更改D盤下的123.txt文件的時間time;
3)使用Date()構造函數將time轉換成Date時間類的對象d;
4)創建SimpleDateFormat類的對象sdf,時間格式是:yyyy-MM-dd HH:mm:ss;
5)使用格式化解析器對象sdf調用format函數將日期時間對象d轉換為字符串sTime,并輸出;

獲取函數代碼演示如下所示:


7.png

2.4、創建方法

由于File類既可以表示文件,也可以表示文件夾(目錄)。Java針對File類的創建方法給出2類,一類是創建文件的方法,一類是創建文件夾的方法。

1、創建文件


8.png

可以創建一個文件,返回的boolean值表示文件是否創建成功。
true :表示創建文件成功; false :表示創建文件失敗,失敗原因基本是因為當前的目錄有了相同的文件;
需求:創建:D:\abc\1.txt文件。在D盤的abc文件夾下新創建一個1.txt文件。
分析和步驟:
1)創建File類的對象file,指定目錄和文件名;
2)使用file對象調用createNewFile()函數創建文件,并打印返回值;


9.png

說明:
1)createNewFile()函數表示 把封裝的File類的對象創建成一個文件,
如果指定的路徑沒有創建的文件,則會創建文件,返回值是true,創建成功;
如果同名的文件已經存在,則不會再創建文件,返回false,創建失敗;
如果指定的路徑不存在,這時就會拋異常 Java.io.IOException:系統找不到指定的路徑。這時是不會去創建文件的;
2)只要使用createNewFile()函數創建出來的一定是文件,不管有沒有擴展名。如果指定的文件沒有擴展名,那么也會創建沒有擴展名的文件;
補充:在計算機中,一個文件是可以沒有擴展名的。
3)創建File類的對象時,如果找不到創建文件的路徑就會報上述異常:Java.io.IOException;

2、創建文件夾


10.png

mkdir() 函數表示創建單級目錄。如果創建文件夾中存在要創建的文件夾,則返回false,創建失敗,
如果創建超過一個目錄,也會返回false。前提是這個多級目錄在計算機上都沒有存在。
如果是多級目錄,但是多級目錄除了最后一個目錄,前面目錄都存在,那么也會返回true,創建成功。
mkdirs() 函數表示一次創建多級目錄。創建單級目錄也可以,如果創建文件夾中存在此文件夾,
則返回false,創建失敗。

需求:創建一個多目錄文件夾D:\aaa\bbb\ccc
分析和步驟:
1)創建File類的對象file,指定創建的目錄;
2)使用file對象分別調用mkdir() 和mkdirs() 函數創建文件夾,并打印返回值;


11.png

需求:使用mkdirs()函數創建一個D:\abc\1.jpg 的文件夾。


12.png

注意:
1):創建文件或文件夾時,一定要調用正確的方法。
騎著白馬的不一定是王子,也有可能是唐僧;
長著翅膀的不一定是天使,也有可能是鳥人;
名字叫.jpg的不一定是文件,也有可能是文件夾;

舉例:new File(“D:\abc\1.jpg”);
A:如果使用File類的對象創建文件夾,那么在硬盤上就會生成一個文件夾。名字為1.jpg.
而此時如果在使用createNewFile()在創建1.jpg文件,也不會創建成功;
B:注意啦 如果創建文件夾的時候,當前目錄中存在一個文件的全名(文件名+后綴名)和要創建文件夾同名,那么也不會創建該文件夾;
舉例:比如我要創建:

13.png

結果在D:\abc文件夾下面有一個文件的名字叫做:1.jsp文件名
此時不會創建成功。
2):絕對路徑和相對路徑創建文件或者文件夾的問題。
絕對路徑:有根目錄的路徑
相對路徑:沒有根目錄的路徑
我們創建一個文件或文件夾時,如果使用了相對路徑,會在項目目錄下創建。

2.5、刪除方法

14.png

boolean delete() 刪除File類對象中的文件或文件夾。


15.png

注意:
1)delete()函數的刪除不走回收站。謹慎使用。
2)delete()函數可以刪除文件或者文件夾,但是刪除文件夾的時候,要求文件夾一定是空的。也就是說如果一個文件夾中有兒子,那么不能直接刪除該文件夾。

2.6、判斷方法

File類既可以描述文件,也可以描述文件夾。那么File類中就給出了判斷當前File對象封裝的對象到底是文件還是文件夾。


16.png
17.png

public boolean isDirectory() 是否是文件夾 如果是文件夾 返回 true 否則返回false;
public boolean isFile() 是否是文件 如果是文件 返回 true , 否則返回false;
public boolean isHidden() 是否隱藏 如果是隱藏文件或者文件夾 返回 true , 否則返回false;
public boolean exists() 是否存在 如果File類對象中的文件或者文件夾在硬盤上存在 返回 true ,否則返回false;

代碼演示如下所示:


18.png

2.7、列舉方法

有時我們需要獲取指定目錄下的文件或文件夾。所以我們可以采用以下方法來獲取。


19.png

list()它是獲取指定目錄(文件夾)下的所有文件或文件夾,把這些文件或文件夾的名字保存在返回的字符串數組中。
可以理解為獲取當前目錄下的所有兒子的名稱的數組。

需求:掃描D:\test下的所有子文件和子文件夾,并且打印子文件或者子文件夾名。
分析和步驟:
1):創建父目錄D:\test的File對象dir;
2):使用dir對象調用list()函數獲取所有兒子的數組,數組名叫做dirs;
3):使用foreach循環遍歷dirs,打印數組中存放的文件或者文件夾名;

//需求:掃描D:\\test下的所有子文件和子文件夾,并且打印子文件或者子文件夾名。
    public static void method_1() {
        // 創建File類的對象
        File file = new File("D:\\test");
        //使用file對象調用list()函數所有的兒子文件或者文件夾
        String[] dirs = file.list();
        //循環遍歷數組
        for (String dir : dirs) {
            System.out.println(dir);
        }
    }

上述代碼結果:
1.jsp
1.mp3
1.txt
123
說明:每個字符串是一個文件名,而不是一條完整路徑。也就是說list()函數獲取的子文件或者子文件夾的名字。
上述函數雖然可以獲得文件或者文件夾名字,但是都變成字符串了,在開發中用處不是太大,我們更希望獲得的是文件或者文件夾的對象,這樣操作會更廣泛。

20.png

listFiles()它也是獲取指定目錄下的文件和文件夾,但把這些文件和文件夾的名字重新封裝成一個一個獨立的File對象,把這些File對象保存在File數組中,最后返回這個File數組。
也可以理解為獲取當前目錄下的所有兒子File對象的數組。
需求:掃描D:\test下的所有子文件和子文件夾,打印出哪些是文件夾哪些是文件。
分析和步驟:
1):創建父目錄D:\test的File對象dir;
2):使用dir對象調用listFiles()函數獲取所有兒子的對象數組,數組名叫做files;
3):使用foreach循環遍歷files,獲取每個文件或者文件夾的對象file;
4):使用file對象調用isDirectory()判斷此時file對象是否是文件夾,如果是,則打印文件夾,否則說明是文件,打印文件;

//需求:掃描D:\\test下的所有子文件和子文件夾,打印出哪些是文件夾哪些是文件。
    public static void method_2() {
        // 創建File類的對象
        File file = new File("D:\\test");
        //根據file對象調用listFiles()函數獲得上述文件夾中的所有兒子文件和文件夾
        File[] dirs = file.listFiles();
        //遍歷數組獲得File類的對象
        for (File dir : dirs) {
           // System.out.println(dir);
            /*
             * 如果想輸出哪些是文件夾哪些是文件,由于File類中要么是文件要么是文件夾
             * 所以我們可以先獲得文件夾,然后打印,則另一個就是文件
             * dir.isDirectory() 如果為true,說明是文件夾
             * dir.getName()表示獲得文件或者文件夾的名字
             */
            if(dir.isDirectory())
            {
                //說明是文件夾
                System.out.println(dir.getName()+"是文件夾");
            }else
            {
                //說明是文件
                System.out.println(dir.getName()+"是文件");
            }
        }
    }

說明:
1、如果想輸出哪些是文件夾哪些是文件,由于File類中要么是文件要么是文件夾。所以我們可以先獲得文件夾,然后打印,則另一個就是文件。
dir.isDirectory() 如果為true,說明是文件夾;
dir.getName() 表示獲得文件或者文件夾的名字;
2、當使用foreach循環的時候,執行System.out.println(dir);這個代碼的時候,打印的結果如下:


21.png

注意:listFiles()函數表示獲得的每個路徑名都是絕對路徑名。

3、文件過濾器(難)

3.1、文件過濾器介紹

過濾器:它就是把不需要的過濾出去,留下需要的內容。
文件或文件夾過濾器:過濾掉不需要的文件或文件夾,留下需要的文件或文件夾。
有種需求可以考慮使用過濾器:

假設在一個父目錄文件夾下有成千上萬個文件或者文件夾,而后綴名為.jpg的文件只有幾個,我想把后綴名為.jpg的文件找出來,其實使用我們剛才講解的list()和listFiles()函數可以解決,但是比較麻煩,主要是麻煩在某個類中或者某個項目中寫完之后想要在其他項目使用,還得書寫,也就是可移植性不是太好,那么我們是否可以想出一個可移植性好的辦法呢,寫完一次,其他地方可以再用,提高效率簡化代碼開發。
答案是可以的,過濾器就可以實現。

3.2、FilenameFilter接口(文件名過濾器)

22.png

accept:方法是用來書寫具體過濾的條件的。
dir參數:是當前name所表示的文件或文件夾所在的父目錄。
name參數:是需要過濾的那個文件夾的名字或者文件的整體名字(包括文件的后綴名,例如123.java 或者mm.jpg)。

舉例:想過濾 D:\test\123.java 下面的123.Java文件,如果想使用這個accept(dir,name)函數,
那么dir 表示D:\test,而name表示123.java。
注意:這個接口沒有實現類,如果我們想使用這個接口中的函數,我們需要自己定義實現類并復寫accept()函數。

File類中的函數:
public String[] list(FilenameFilter filter) 返回符合過濾器中條件的兒子的名稱的字符串數組
public File[] listFiles(FilenameFilter filter) 返回符合過濾器中條件的兒子的File對象數組

需求:判斷D:\test下是否有.jpg文件,如果有,則打印其絕對路徑。
分析和步驟:
1)創建測試類FilenameFilterDemo;
2)在FilenameFilterDemo類中main函數中創建父目錄File類的對象parent,"D:\test"作為函數的參數;
3)使用對象parent調用list()函數獲取所有符合條件的兒子的名稱數組names,自定義過濾器類的對象new MyFilenameFilter()作為參數;
4)循環遍歷數組names,獲取每個兒子;
5)創建File類的對象重新封裝兒子的對象file;
6)使用file對象調用getAbsolutePath()函數獲得D:\test文件夾下含有文件.jpg的絕對路徑,輸出并打印;
7)上述方案也可以換另一種方式實現,父目錄對象可以調用listFiles()函數來獲得符合過濾器中條件的兒子的File對象數組;
使用public String[] list(FilenameFilter filter) 函數方式來實現過濾功能。

測試類代碼如下:

package cn.xuexi.file.filter.demo;
import java.io.File;
/*
 * FilenameFilter過濾器的演示
 * 需求:判斷D:\\test下是否有.jpg文件,如果有,則打印其絕對路徑。
 */
public class FileNameFilterDemo {
    public static void main(String[] args) {
        method_1();
    }
    //  public String[] list(FilenameFilter filter) 返回符合過濾器中條件的兒子的名稱的字符串數組
    public static void method_1() {
        // 創建File類的對象
        File file = new File("D:\\test");
        /*
         * 使用file對象調用list(FilenameFilter filter) 函數來篩選D:\\test
         * 目錄下兒子文件后綴名是.jpg
         */
        //獲得符合條件的兒子的名字的數組
        String[] names = file.list(new MyFilenameFilter());
        //遍歷數組
        for (String name : names) {
            /*
             * 這里的name就是表示D:\\test目錄下符合條件的兒子的名字
             * 也就是說name在這里就是所有后綴名為.jpg的文件名字
             * 如D:\\test目錄下的1.jpg文件
             * 由于題目需求是想獲得兒子文件的絕對路徑
             * 想獲得絕對路徑必須得調用File類中的getAbsolutePath()函數
             * 而這個函數是非靜態函數得通過File的對象調用
             * 所以接下來我們要獲得File類的對象
             */
            //使用File類的構造函數封裝兒子的對象 file2代表后綴名是.jpg的文件的對象
            File file2 = new File(file,name);
            System.out.println(file2.getAbsolutePath());
        }
    }

過濾器類代碼實現:
說明:對FilenameFilter接口中的accept函數進行進一步說明:
這個方法中定義過濾條件,當我們調用list或者listFiles方法的時候,會把每個兒子都拿來調用accept方法:
如果這個方法返回true,那么這個兒子會被添加到最終的數組中;
如果這個方法返回false,那么這個兒子就不會被添加到最終的數組;
1)創建一個過濾器類MyFilenameFilter 并實現FilenameFilter接口,然后復寫接口中的accept()函數;
2)在accept函數定義過濾條件來判斷每個兒子是否符合要求,符合就返回true,否則返回false;
3)創建File類的對象封裝兒子的對象file;
4)定義一個boolean類型的變量flag來接收name的后綴名是否是.jpg,并且必須是文件的布爾值;
5)返回flag的值;

package cn.xuexi.file.filter.demo;
import java.io.File;
import java.io.FilenameFilter;
/*
 * 過濾名字的過濾器
 */
public class MyFilenameFilter implements FilenameFilter{
    public boolean accept(File dir, String name) {
        /*
         * 我們需要在這里書寫過濾條件,判斷兒子是否符合條件
         * 符合,則返回true
         * 不符合,則返回false
         * dir表示父目錄
         * name 表示兒子(文件或者文件夾)的名字 例如 1.jpg
         */
        //輸出dir 和 name 
//      System.out.println(dir+"---"+name);
        /*
         * 這里的兒子名字name都是String類型,而我們又想獲取name的后綴名是.jpg
         * 所以也就是說我們需要判斷字符串name的后面是否是.jpg,
         * 如果是就返回true,存儲到數組中,否則不存儲
         */
        //判斷name的后綴名是否是.jpg
        boolean boo = name.endsWith(".jpg");
        /*
         * 還得判斷兒子是否是文件 但是這里的name是字符串不能調用isFile()函數
         * 所以只能將兒子的名字name封裝成File類的對象
         */
        File file = new File(dir,name);
        //判斷兒子是否是文件 true 是文件 false不是文件
        boolean boo2 = file.isFile();
        return boo && boo2;
    }
}

使用public File[] listFiles(FilenameFilter filter) 函數方式來實現過濾功能。
測試類代碼如下:

//public File[] listFiles(FilenameFilter filter) 返回符合過濾器中條件的兒子的File對象數組
        public static void method_2() {
            // 創建File類的對象
            File file = new File("D:\\test");
            /*
             * 使用file對象調用list(FilenameFilter filter) 函數來篩選D:\\test
             * 目錄下兒子文件后綴名是.jpg
             */
            //獲得符合條件的兒子的名字的數組
            File[] files = file.listFiles(new MyFilenameFilter());
            //遍歷數組
            for (File file2 : files) {
                /*
                 * 這里的file2就是表示D:\\test目錄下符合條件的兒子的對象
                 * 也就是說file2在這里就是所有后綴名為.jpg的文件的對象
                 * 如D:\\test目錄下的1.jpg文件
                 * 由于題目需求是想獲得兒子文件的絕對路徑
                 * 想獲得絕對路徑必須得調用File類中的getAbsolutePath()函數
                 * 而這個函數是非靜態函數得通過File的對象調用
                 * 所以這里直接使用file2調用即可
                 */
                System.out.println(file2.getAbsolutePath());
            }
        }
}

過濾器源碼實現來說明FilenameFilter過濾器中accept()函數執行的時間:


23.png

說明:FilenameFilter:過濾器僅僅只能根據accept方法中name中包括的字符內容過濾當前的文件或文件夾。而不能直接去判斷當前以name表示的那個字符串到底是文件還是文件夾,只能間接的重新封裝name對象,然后根據封裝后的對象調用isFile()函數判斷是否是文件,雖然這樣可以解決問題,但是不建議開發中使用上述這種方式。
Java中又給我們提供了一個比較簡單的實現方式就是過濾器FileFilter。

3.3、FileFileter介紹

FileFilter:它也是一個過濾器,專門用來過濾文件或文件夾的。


24.png

File類中的函數:
File[] listFiles(FileFilter filter) 返回符合過濾器條件的所有兒子的File數組
FileFilter過濾器中的accept方法中的pathname是當前需要過濾的那個文件或文件夾對象。
或者可以這么理解pathname:就是某個兒子的File對象。
這里的File pathname參數相當于:FilenameFilter過濾器中的自定義過濾器類MyFilenameFilter里面的代碼:

File file=new File(dir,name);

需求:判斷D:\test下是否有.jpg文件,如果有,則打印其絕對路徑。
分析和步驟:
1)創建測試類FilenameFilterDemo1;
2)在FilenameFilterDemo1類中main函數中創建父目錄File類的對象parent,"D:\test"作為函數的參數;
3)使用對象parent調用listFiles()函數獲取所有符合條件的兒子的File數組files,自定義過濾器類的對象new MyFilenameFilter()作為參數;
4)循環遍歷數組files,獲取每個兒子file;
5)使用file對象調用getAbsolutePath()函數獲得D:\test文件夾下含有文件.jpg的絕對路徑,輸出并打印;
測試類代碼:

package cn.xuexi.file.filter.demo;
import java.io.File;
/*
 * 演示文件過濾器 FileFilter
 * 需求:判斷D:\\test下是否有.jpg文件,如果有,則打印其絕對路徑。
 */
public class FileFilterDemo {
    public static void main(String[] args) {
        // 創建父目錄D:\\test的對象
        File file = new File("D:\\test");
        /*
         * 使用父目錄對象file調用listFiles(FileFilter filter) 
         * 獲得符合過濾器條件的兒子對象
         */
        File[] files = file.listFiles(new MyFileFilter());
        //遍歷兒子對象的數組 file2表示符合條件的兒子對象
        for (File file2 : files) {
            //輸出絕對路徑
            System.out.println(file2.getAbsolutePath());
        }
    }
}

過濾器類代碼實現:
說明:對FileFilter接口中的accept函數進行進一步說明:
這個方法中定義過濾條件,當我們調用listFiles方法的時候,會把每個兒子都拿來調用accept方法:
如果這個方法返回true,那么這個兒子會被添加到最終的數組中
如果這個方法返回false,那么這個兒子就不會被添加到最終的數組
1)創建一個過濾器類MyFileFilter 并實現FileFilter接口,然后復寫接口中的accept()函數;
2)在accept函數定義過濾條件來判斷每個兒子是否符合要求,符合就返回true,否則返回false;
3)使用File類的對象pathname調用getName()然后調用String類中的endsWith()函數判斷文件名的后綴名是否是.jpg;
4)使用File類的對象pathname函數調用isFile()判斷是否是文件;
5)使用return關鍵字將上述兩個布爾類型的值返回;

package cn.xuexi.file.filter.demo;
import java.io.File;
import java.io.FileFilter;
/*
 * 自定義文件過濾器
 */
public class MyFileFilter implements FileFilter {
    public boolean accept(File pathname) {
        /*
         * 這里的pathname表示兒子的File類的對象
         * 這里的pathname就相當于FilenameFilter過濾器中的
         * new File(dir,name);
         */
//      System.out.println("======="+pathname);
        /*
         * 兒子對象有了,我們可以調用函數判斷兒子是否是文件
         */
        boolean boo = pathname.isFile();
        /*
         * 接下來我們要判斷兒子屬于文件,文件的后綴名是否是.jpg
         * 那么我們要獲得兒子的名字 getName()函數可以實現
         */
        String name = pathname.getName();
        //判斷字符串name的后綴名是否是.jpg
        boolean boo2 = name.endsWith(".jpg");
        return boo && boo2;
    }
}

升級一下需求:獲取D:\test下的所有任意指定類型的文件,打印絕對路徑

分析:
原來:我們把判斷條件寫死成".jpg",所以只能判斷掃描.jpg文件。
現在:我們要判斷任意類型的文件,那么就不能寫死。用戶讓我們過濾什么,我們就過濾什么。
說明:對于這里的程序來說,用戶就是使用過濾器的地方,就是創建過濾器類對象的地方。
那么,過濾的條件需要讓用戶傳遞給過濾器。
用戶調用過濾器的時候,僅僅是創造了過濾器類的構造函數,所以,我們考慮用構造函數傳遞參數。
過濾器類的代碼如下所示:

package cn.xuexi.file.filter.demo;
import java.io.File;
import java.io.FileFilter;
/*
 * 自定義文件過濾器
 */
public class MyFileFilter implements FileFilter {
    //定義一個成員變量 代表后綴名
    public String suffix;
    //定義構造函數 接收調用傳遞過來的文件后綴名
    public MyFileFilter(String suffix)
    {
        this.suffix=suffix;
    }
    public boolean accept(File pathname) {
        /*
         * 這里的pathname表示兒子的File類的對象
         * 這里的pathname就相當于FilenameFilter過濾器中的
         * new File(dir,name);
         */
//      System.out.println("======="+pathname);
        /*
         * 兒子對象有了,我們可以調用函數判斷兒子是否是文件
         */
        boolean boo = pathname.isFile();
        /*
         * 接下來我們要判斷兒子屬于文件,文件的后綴名是否是.jpg
         * 那么我們要獲得兒子的名字 getName()函數可以實現
         */
        String name = pathname.getName();
        //判斷字符串name的后綴名是否是.jpg
//      boolean boo2 = name.endsWith(".jpg");
        //判斷字符串name的后綴名是否是suffix 這里的suffix由調用者決定
        boolean boo2 = name.endsWith(suffix);
        return boo && boo2;
    }
}

測試類的代碼如下所示:

package cn.xuexi.file.filter.demo;
import java.io.File;
/*
 * 演示文件過濾器 FileFilter
 * 需求:判斷D:\\test下是否有.jpg文件,如果有,則打印其絕對路徑。
 */
public class FileFilterDemo {
    public static void main(String[] args) {
        // 創建父目錄D:\\test的對象
        File file = new File("D:\\test");
        /*
         * 使用父目錄對象file調用listFiles(FileFilter filter) 
         * 獲得符合過濾器條件的兒子對象
         * 想要的文件類型由調用者決定 .txt
         */
        File[] files = file.listFiles(new MyFileFilter(".txt"));
        //遍歷兒子對象的數組 file2表示符合條件的兒子對象
        for (File file2 : files) {
            //輸出絕對路徑
            System.out.println(file2.getAbsolutePath());
        }
    }
}

上述兩個過濾器類的圖解說明如下所示:


25.png
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,973評論 19 139
  • 我們要想實現IO的操作,就必須知道硬盤上文件的表現形式。而Java就提供了一個類File供我們使用。所以這篇我們來...
    清風沐沐閱讀 2,929評論 1 9
  • 今天好朋友們聚會,這幾位朋友也有十多年的革命友情了,每年一次,無論年前還是年后。以前,聚會都不帶家屬,因為單身的居...
    簡茉陌閱讀 319評論 19 0
  • 新的一年開始了,寫點東西紀念一下。 對于地球來說,每一天都一樣,對于我們來說,人為的分為逝去的日子,新年里的日子,...
    ajin1973閱讀 146評論 0 3
  • p2p金融新聞 p2p金融新聞 p2p金融新聞
    東孕業47310閱讀 245評論 0 0