探究Java File类中list()、listFiles()的使用及区别,认识和使用匿名内部类
轉載自? ? ?探究Java File類中list()、listFiles()的使用及區別,認識和使用匿名內部類
?
內容概要:
1、認識File類;
2、File的構造函數;
3、list()及其重載方法的使用,匿名內部類的兩種使用方式;
4、listFiles()方法和list()方法的區別,listFiles()及其重載方法的使用。
?
--------------------------------1、認識File類--------------------------------
File類的名字會有一定的誤導性:我們很容易的認為它指代的是文件。實際上并不是這樣的。
其實它解決的是文件或者是文件夾的路徑問題。如果使用FilePath這個名字會更好些(可惜Java最初沒有這么做)。
?
--------------------------------2、File的構造函數---------------------------
?File類的構造函數有以下幾種:
?1)、File(String pathname)?
?2)、File(String parent, String child)?
?3)、File(File parent, String child)
?4)、File(URI uri)?
構造的File類對象表示一個路徑,指向我們的目標文件或文件夾。
File path = new File("."); ?表示當前目錄。
File?path = new File("E:\\Java"); 表示Windows下的E盤里的Java文件(或者是文件夾),注意要用雙斜線\\。
File?path = new File(new File("."),"bin"); 表示當前文件夾下的bin文件(文件夾),如果沒有bin就會拋出NullPointerException異常。
?
--------------------------------3、list()及其重載方法的使用,匿名內部類的兩種使用方式---------------------------
list()方法 : 會返回一個字符數組,將制定路徑下的文件或文件夾名字存儲到String數組中。因為其返回的是一個String類型的數組,所以它也就只是一個名字而已(后面要講到的listFiles()及其重載方法則不同,它們返回的是File類型的對象,所以具有其全部的屬性和方法)。有以下兩種重載方式:
1)、String[] ?list()
2)、String[] ?list(FilenameFilter filter)
?
下面是File構造函數和list()方法的簡單應用:
package com.lj95801.iosystem; import java.io.File; import org.junit.Test; public class tFile1 { /* * File類的構造函數有以下幾種: * 1)、File(File parent, String child); * 2)、File(String pathname) * 3)、File(String parent, String child) * 4)、File(URI uri) */ @Test public void test1(){ //1、new File(".")構建的是當前目錄的路徑 File path = new File("."); String[] list = path.list(); for(String itemName : list){ System.out.println(itemName); } //2、new File("E:\\Java")利用絕對路徑構建E盤下的Java目錄路徑 System.out.println("--------->"); path = new File("E:\\Java"); list = path.list(); for(String itemName : list){ System.out.println(itemName); } //3、new File(new File("."),"bin")表示當前目錄下的bin目錄 System.out.println("--------->"); path = new File(new File("."),"bin"); list = path.list();//列出bin目錄下的所有文件或者是文件夾 for(String itemName : list){ System.out.println(itemName); } } }運行結果如下:
?
下面進一步講String[] ?list(FilenameFilter filter)和匿名內部類的用法。
FilenameFilter filter是一個目錄過濾器。list(FilenameFilter filter)方法會選擇符合條件的文件或文件夾。為了能理解這個函數的工作原理,下面列出了其源碼(這個是Java類庫中的源碼,注釋是我自己添加的):
public String[] list(FilenameFilter filter) { String names[] = list(); //首先還是調用<span style="font-family: Arial, Helvetica, sans-serif;">list()方法,獲取指定目錄下的全部文件(夾)名字</span> if ((names == null) || (filter == null)) { //<span style="font-family: Arial, Helvetica, sans-serif;">filter == null說明沒有過濾條件</span> return names; } ArrayList v = new ArrayList(); for (int i = 0 ; i < names.length ; i++) { //遍歷names[]數組中的所有文件(夾)名字 if (filter.accept(this, names[i])) { //如果<span style="font-family: Arial, Helvetica, sans-serif;">accept()方法返回真,則添加到ArrayList中</span> v.add(names[i]); } } return (String[])(v.toArray(new String[v.size()])); //將<span style="font-family: Arial, Helvetica, sans-serif;">ArrayList轉換成String[]類型返回</span> }可以看出,list(FilenameFilter filter)方法保存的是那些能夠使filter.accept()方法返回true的文件名。
?
list(FilenameFilter filter)的原理明白了,現在的問題是accept()方法又是怎么回事呢?
首先,filter.accept(this, names[i]);就可以看出,這是FilenameFilter中的方法。繼續往上追溯FilenameFilter的源代碼如下:
public interface FilenameFilter { /** * Tests if a specified file should be included in a file list. * * @param dir the directory in which the file was found. * @param name the name of the file. * @return <code>true</code> if and only if the name should be * included in the file list; <code>false</code> otherwise. */ boolean accept(File dir, String name); }好!!終于明白了,FilenameFilter是一個接口。
現在理一下思路:
list(FilenameFilter filter)方法??---------調用了------->?filter對象中的accept(File dir, String name)方法 ------>?FilenameFilter是一個接口。
accept()方法會返回一個boolean類型的值,list()方法會根據這個返回值來決定是不是要將某個名字添加到返回列表中。所以,我們要在accept()方法中定義好挑選條件,由于是字符的選取,這會用到正則表達式。
所以,要使用list(FilenameFilter filter)方法就必須實現FilenameFilter接口,accept方法由我們自己定義,所以你想要讓什么樣的文件名能夠使得accept方法返回ture(等價的就是你想要什么樣的文件名能夠被list方法返回)都由你自己決定了。
?
下面來看一看如何使用list(FilenameFilter filter)方法:
package com.lj95801.iosystem; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.util.regex.Pattern; import org.junit.Test; public class tFile2 { /* * list()方法 : 會返回一個字符數組,將制定路徑下的文件或文件夾名(僅僅是個名字而已)存儲到String數組中。有<span style="white-space:pre"> </span> * 以下幾種: * 1)、list() * 2)、list(FilenameFilter filter) * * FilenameFilter filter是一個目錄過濾器。list(FilenameFilter filter)方法會選擇 * 符合條件的文件或文件夾。為了能理解這個函數的工作原理,下面列出了其源碼: * public String[] list(FilenameFilter filter) { String names[] = list(); if ((names == null) || (filter == null)) { return names; } ArrayList v = new ArrayList(); for (int i = 0 ; i < names.length ; i++) { if (filter.accept(this, names[i])) { v.add(names[i]); } } return (String[])(v.toArray(new String[v.size()])); } *我們再往前追蹤一下,看看FilenameFilter到底是怎樣的,同時其accept()方法又有什么作用: * interface FilenameFilter { * * Tests if a specified file should be included in a file list. * * @param dir the directory in which the file was found. * @param name the name of the file. * @return <code>true</code> if and only if the name should be * included in the file list; <code>false</code> otherwise. boolean accept(File dir, String name); } * *我們可以看到,FilenameFilter只是一個接口,所以如果要用list(FilenameFilter filter)方法 *我們必須要實現這樣的一個接口。accept()方法會返回一個boolean類型的值,list()方法會根據這個返回值 *來決定是不是要將某個名字添加到返回列表中。所以,我們要在accept()方法中定義好挑選條件,這會用到正則表達式。 * */ //一、采用實現接口的方式 class FileNameFilter1 implements FilenameFilter{ private Pattern pattern; public FileNameFilter1(String regex) { pattern = Pattern.compile(regex); } @Override public boolean accept(File dir, String name) { boolean result = pattern.matcher(name).matches(); return result; } } /* * 二、采用匿名內部類的方式。 * 不用implements的方式來實現接口,但是定義一個靜態方法,此靜態方法返回一個FilenameFilter對象, * 本來正常的語句是return new FilenameFilter();但是在語句結束之前我說“等一下,我要在這里定義 * 一個類,類的具體實現我用一個大括號括起來”。 */ static class FileNameFilter2{ public static FilenameFilter filter(final String regex){ return new FilenameFilter(){ private Pattern pattern = Pattern.compile(regex); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }; } } @Test public void test2(){ System.out.println("------挑選當前目錄下以.開頭的文件或文件夾-------"); //1、挑選當前目錄下以.開頭的文件或文件夾,并且打印出來(創建一個類來實現FilenameFilter接口) File path = new File("."); String[] nameList = path.list(new FileNameFilter1("\\..*")); for(String itemName : nameList){ System.out.println(itemName); } System.out.println("------挑選當前目錄下以b開頭的文件或文件夾-------"); //2、挑選當前目錄下以b開頭的文件或文件夾,并且打印出來(使用匿名內部類的方式來實現) File path2 = new File("."); String[] nameList2 = path2.list(FileNameFilter2.filter("b.*")); for(String itemName : nameList2){ System.out.println(itemName); } System.out.println("------挑選當前目錄下以s開頭的文件或文件夾-------"); //3、將匿名內部類利用到極致 File path3 = new File("."); String[] nameList3 = path3.list(new FilenameFilter(){//其實是在第二種方式的基礎上精簡過來的。 private Pattern pattern = Pattern.compile("s.*"); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); for(String itemName : nameList3){ System.out.println(itemName); } } }
執行結果如下:
--------------------------------4、listFiles()方法和list()方法的區別,listFiles()及其重載方法的使用---------------
list()和listFiles()方法的區別在于:
list()返回的是一個String類型數組,它只是一個數組,僅僅只是一個文件(文件夾)的名字而已;
而listFiles()方法返回的是一個File類的引用,它具有類的所有屬性和方法,比如:String?getName()方法就能夠返回該文件的String類型的文件名(名字而已)。
下面的前三個方法返回File[]類型,第四個返回static File[]類型。
返回類型 : 該路徑下所有文件或文件夾的絕對路徑(pathname,注意File類型指的是路徑,而不是文件)
listFiles()
listFiles(FileFilter filter)
listFiles(FilenameFilter filter)
listRoots()
?
我們可以追蹤一下FileFilter接口的源代碼,加深理解(其實和FilenameFilter差不多):
public interface FileFilter { /** * Tests whether or not the specified abstract pathname should be * included in a pathname list. * * @param pathname The abstract pathname to be tested * @return <code>true</code> if and only if <code>pathname</code> * should be included */ boolean accept(File pathname); }也要實現accept方法,但是傳入的參數不一樣,它是File類型的。這樣的話就好辦了。
比如說,我要挑選文件夾:
class FileDirectory implements FileFilter{ @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }再比如說,我要挑選可執行文件:
class FileDirectory implements FileFilter{ @Override public boolean accept(File pathname) { return pathname.canExecute(); } }下面給出一個例子,說明用法:
package com.lj95801.iosystem; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.util.regex.Pattern; import org.junit.Test; public class tFile3 { /* * list()和listFiles()方法的區別在于:list()返回的是一個String類型數組,它只是一個數組; * 而listFiles()方法返回的是一個File類的引用,它具有類的所有屬性和方法。 * * 下面的前三個方法返回File[]類型,第四個返回static File[]類型。 * 返回類型 : 該路徑下所有文件或文件夾的絕對路徑(pathname,注意File類型指的是路徑,而不是文件) * listFiles() * listFiles(FileFilter filter) * listFiles(FilenameFilter filter) * listRoots() * */ @Test public void test3(){ System.out.println("-----判別當前目錄下的文件是否為文件夾----"); //1、列出當前目錄下的所有文件和文件夾,保存為File類對象的數組,判別其是否為文件夾 File path = new File("."); File[] files = path.listFiles(); for(File f : files){ System.out.println(f + " ---> is a Directory? " + f.isDirectory()); } System.out.println("-----挑選出當前目錄下的所有文件夾----"); //2、挑選出當前目錄下的所有文件夾 File path2 = new File("."); File[] files2 = path2.listFiles(new FileFilter(){ @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }); for(File f : files2){ System.out.println(f); } System.out.println("-----挑選出當前目錄下的所有以s開頭的文件夾----"); //2、挑選出當前目錄下的所有以s開頭的文件夾 File path3 = new File("."); File[] files3 = path3.listFiles(new FileFilter(){ @Override public boolean accept(File pathname) { Pattern pattern = Pattern.compile("s.*"); return pathname.isDirectory()&&pattern.matcher(pathname.getName()).matches(); } }); for(File f : files3){ System.out.println(f); } System.out.println("-----挑選出當前目錄下的所有以.開頭的文件夾,并且標明文件屬性----"); //3、挑選出當前目錄下以.開頭的文件或文件夾,并且在其后部標明f/d標明其為文件或文件夾 File path4 = new File("."); File[] files4 = path4.listFiles(new FilenameFilter(){ Pattern pattern = Pattern.compile("\\..*"); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); for(File f : files4){ String sfd = (f.isFile()) ? "f" : "d"; System.out.println(f.getName() + "---->" + sfd); } } }執行結果如下:
?
----------------------------------------------下面是整個演示源代碼----------------------------------------------
package com.lj95801.iosystem; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.util.regex.Pattern; import org.junit.Test; public class tFile1 { /* * File類的構造函數有以下幾種: * 1)、File(File parent, String child); * 2)、File(String pathname) * 3)、File(String parent, String child) * 4)、File(URI uri) */ @Test public void test1(){ //1、new File(".")構建的是當前目錄的路徑 File path = new File("."); String[] list = path.list(); for(String itemName : list){ System.out.println(itemName); } //2、new File("E:\\Java")利用絕對路徑構建E盤下的Java目錄路徑 System.out.println("--------->"); path = new File("E:\\Java"); list = path.list(); for(String itemName : list){ System.out.println(itemName); } //3、new File(new File("."),"bin")表示當前目錄下的bin目錄 System.out.println("--------->"); path = new File(new File("."),"bin"); list = path.list();//列出bin目錄下的所有文件或者是文件夾 for(String itemName : list){ System.out.println(itemName); } } /* * list()方法 : 會返回一個字符數組,將制定路徑下的文件或文件夾名(僅僅是個名字而已)存儲到String數組中。有以下幾種: * 1)、list() * 2)、list(FilenameFilter filter) * * FilenameFilter filter是一個目錄過濾器。list(FilenameFilter filter)方法會選擇 * 符合條件的文件或文件夾。為了能理解這個函數的工作原理,下面列出了其源碼: * public String[] list(FilenameFilter filter) { String names[] = list(); if ((names == null) || (filter == null)) { return names; } ArrayList v = new ArrayList(); for (int i = 0 ; i < names.length ; i++) { if (filter.accept(this, names[i])) { v.add(names[i]); } } return (String[])(v.toArray(new String[v.size()])); } *我們再往前追蹤一下,看看FilenameFilter到底是怎樣的,同時其accept()方法又有什么作用: * interface FilenameFilter { * * Tests if a specified file should be included in a file list. * * @param dir the directory in which the file was found. * @param name the name of the file. * @return <code>true</code> if and only if the name should be * included in the file list; <code>false</code> otherwise. boolean accept(File dir, String name); } * *我們可以看到,FilenameFilter只是一個接口,所以如果要用list(FilenameFilter filter)方法 *我們必須要實現這樣的一個接口。accept()方法會返回一個boolean類型的值,list()方法會根據這個返回值 *來決定是不是要將某個名字添加到返回列表中。所以,我們要在accept()方法中定義好挑選條件,這會用到正則表達式。 * */ //一、采用實現接口的方式 class FileNameFilter1 implements FilenameFilter{ private Pattern pattern; public FileNameFilter1(String regex) { pattern = Pattern.compile(regex); } @Override public boolean accept(File dir, String name) { boolean result = pattern.matcher(name).matches(); return result; } } /* * 二、采用匿名內部類的方式。 * 不用implements的方式來實現接口,但是定義一個靜態方法,此靜態方法返回一個FilenameFilter對象, * 本來正常的語句是return new FilenameFilter();但是在語句結束之前我說“等一下,我要在這里定義 * 一個類,類的具體實現我用一個大括號括起來”。 */ static class FileNameFilter2{ public static FilenameFilter filter(final String regex){ return new FilenameFilter(){ private Pattern pattern = Pattern.compile(regex); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }; } } @Test public void test2(){ System.out.println("------挑選當前目錄下以.開頭的文件或文件夾-------"); //1、挑選當前目錄下以.開頭的文件或文件夾,并且打印出來(創建一個類來實現FilenameFilter接口) File path = new File("."); String[] nameList = path.list(new FileNameFilter1("\\..*")); for(String itemName : nameList){ System.out.println(itemName); } System.out.println("------挑選當前目錄下以b開頭的文件或文件夾-------"); //2、挑選當前目錄下以b開頭的文件或文件夾,并且打印出來(使用匿名內部類的方式來實現) File path2 = new File("."); String[] nameList2 = path2.list(FileNameFilter2.filter("b.*")); for(String itemName : nameList2){ System.out.println(itemName); } System.out.println("------挑選當前目錄下以s開頭的文件或文件夾-------"); //3、將匿名內部類利用到極致 File path3 = new File("."); String[] nameList3 = path3.list(new FilenameFilter(){//其實是在第二種方式的基礎上精簡過來的。 private Pattern pattern = Pattern.compile("s.*"); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); for(String itemName : nameList3){ System.out.println(itemName); } } /* * list()和listFiles()方法的區別在于:list()返回的是一個String類型數組,它只是一個數組; * 而listFiles()方法返回的是一個File類的引用,它具有類的所有屬性和方法。 * * 下面的前三個方法返回File[]類型,第四個返回static File[]類型。 * 返回類型 : 該路徑下所有文件或文件夾的絕對路徑(pathname,注意File類型指的是路徑,而不是文件) * listFiles() * listFiles(FileFilter filter) * listFiles(FilenameFilter filter) * listRoots() * */ @Test public void test3(){ System.out.println("-----判別當前目錄下的文件是否為文件夾----"); //1、列出當前目錄下的所有文件和文件夾,保存為File類對象的數組,判別其是否為文件夾 File path = new File("."); File[] files = path.listFiles(); for(File f : files){ System.out.println(f + " ---> is a Directory? " + f.isDirectory()); } System.out.println("-----挑選出當前目錄下的所有文件夾----"); //2、挑選出當前目錄下的所有文件夾 File path2 = new File("."); File[] files2 = path2.listFiles(new FileFilter(){ @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }); for(File f : files2){ System.out.println(f); } System.out.println("-----挑選出當前目錄下的所有以s開頭的文件夾----"); //2、挑選出當前目錄下的所有以s開頭的文件夾 File path3 = new File("."); File[] files3 = path3.listFiles(new FileFilter(){ @Override public boolean accept(File pathname) { Pattern pattern = Pattern.compile("s.*"); return pathname.isDirectory()&&pattern.matcher(pathname.getName()).matches(); } }); for(File f : files3){ System.out.println(f); } System.out.println("-----挑選出當前目錄下的所有以.開頭的文件夾,并且標明文件屬性----"); //3、挑選出當前目錄下以.開頭的文件或文件夾,并且在其后部標明f/d標明其為文件或文件夾 File path4 = new File("."); File[] files4 = path4.listFiles(new FilenameFilter(){ Pattern pattern = Pattern.compile("\\..*"); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); for(File f : files4){ String sfd = (f.isFile()) ? "f" : "d"; System.out.println(f.getName() + "---->" + sfd); } } }?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的探究Java File类中list()、listFiles()的使用及区别,认识和使用匿名内部类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 9个最佳教堂标志"如何免费制作自己的[2
- 下一篇: java.nio.ByteBuffer用