欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java中表示一個文件的File類型詳解

 更新時間:2018年07月03日 09:25:43   作者:Single_Yam  
Java提供File類,讓我們對文件進行操作,下面這篇文章主要給大家介紹了關于java中表示一個文件的File類型的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧

前言

從本篇文章開始,我們將開啟對 Java IO 系統(tǒng)的學習,本質上就是對文件的讀寫操作,聽上去簡單,其實并不容易。Java 的 IO 系統(tǒng)一直在完善和改進,設計了大量的類,也只有理解了這些類型被設計出來的意義以及各自的應用場景,才能提升文件 IO 的理解。

那么,第一步就是要解決如何表示一個文件的問題,Java 世界中「萬物皆對象」,如何將一個實際磁盤文件或目錄對應到一個 Java 對象則是我們首要的問題。

Java 中使用 File 來抽象一個文件,無論是普通文件或是目錄,都可對應于一個 File 對象。我覺得大家對于 File 這個類型的定位一定要準確:它只是抽象的代表了磁盤上的某個文件或目錄,內部實際上是依賴一個平臺無關的本地文件系統(tǒng)類,并且 File 無法對其所表示文件內容進行任何讀寫操作(那是流做的事情)。

構建一個 File 實例

在實際介紹 File 實例構造方法之前,我們得先看看它的幾種重要的屬性成員。

private static final FileSystem fs = DefaultFileSystem.getFileSystem();

這是 File 類中最核心的成員,它表示為當前系統(tǒng)的文件系統(tǒng) API,所有向磁盤發(fā)出的操作都是基于這個屬性的。

private final String path;

path 代表了當前實例的完整路徑名稱,如果當前的 File 實例表示的是目錄的話,那么 path 的值就是這個完整的目錄名稱,如果表示的是純文件的話,那么這個 path 的值等于該文件的完整路徑 + 文件名稱。

public static final char separatorChar = fs.getSeparator();
public static final char pathSeparatorChar = fs.getPathSeparator();

separatorChar 表示的是目錄間的分隔符,pathSeparatorChar 表示的是不同路徑下的分隔符,這兩個值在不同的系統(tǒng)平臺下不盡相同。例如 Windows 下這兩者的值分別為:「」 和 「;」,其中封號用于分隔多個不同路徑。

File 類提供了四種不同的構造器用于實例化一個 File 對象,但較為常用的只有三個,我們也著重學習前三個構造器。

public File(String pathname)

這是最普遍的實例化一個 File 對象的方法,pathname 的值可以是一個目錄,也可以是一個純文件的名稱。例如:

File file = new File("C:\\Users\\yanga\\Desktop");

File file1 = new File("C:\\Users\\yanga\\Desktop\\a.txt");

File file2 = new File("a.txt");

當然也可以顯式指定一個父路徑:

public File(String parent, String child)

在構造器的內部,程序會為我們拼接出一個完整的文件路徑,例如:

File file = new File("C:\\Users\\yanga\\Desktop","a.txt");

File file1 = new File("C:\\Users\\yanga\\Desktop","java");

第三種構造器其實本質上和第二種是一樣的,只不過增加了一個父類 File 實例的封裝過程:

public File(File parent, String child)

類似的情況,不再舉例說明了。我們這里并沒有深究這些構造器的內部具體實現情況,并不是說它簡單,而是 File 過度依賴本地文件系統(tǒng),很多方法的實現情況都不得直接看到,所以對于 File 的學習,定位為熟練掌握即可,具體實現暫時沒法深入學習。

文件名稱或路徑相關信息獲取

getName 方法可以用于獲取文件名稱:

public String getName() {
 int index = path.lastIndexOf(separatorChar);
 if (index < prefixLength) return path.substring(prefixLength);
 return path.substring(index + 1);
}

還記得我們的 separatorChar 表示的是什么了嗎?

它表示為路徑分隔符,Windows 中為符號「」,path 屬性存儲的當前 File 實例的完整路徑名稱,所以最后一次出現的位置后面所有的字符必然是我們的文件名稱。

當然你一定發(fā)現了,對于純文件來說,該方法能夠返回文件的簡單名稱,而對于一個目錄而言,返回值將會是最近的目錄名。例如:

File file = new File("C:\\Users\\yanga\\Desktop\\a.txt");
System.out.println(file.getName());

File file1 = new File("C:\\Users\\yanga\\Desktop");
System.out.println(file1.getName());

輸出結果不會出乎你的意料:

a.txt
Desktop

getParent 方法用于返回當前文件的父級目錄,無論你是純文件或是目錄,你終有你的父目錄(當然,虛擬機生成的臨時文件自然不是)。

public String getParent() {
 int index = path.lastIndexOf(separatorChar);
 if (index < prefixLength) {
 if ((prefixLength > 0) && (path.length() > prefixLength))
 return path.substring(0, prefixLength);
 return null;
 }
 return path.substring(0, index);
}

方法的實現很簡單,不再贅述。

getPath 方法可以返回當前 File 實例的完整文件名稱:

public String getPath() {
 return path;
}

以下是一些有關目錄的相關操作,實現比較簡單,此處簡單羅列了:

  • public boolean isAbsolute():是否為絕對路徑
  • public String getAbsolutePath():獲取當前 File 實例的絕對路徑
  • public String getCanonicalPath():返回當前 File 實例的標準路徑

這里我們需要對 getCanonicalPath 做一點解釋,什么叫標準路徑,和絕對路徑有區(qū)別嗎?

一般而言,「../」表示源文件所在目錄的上一級目錄,「../../」表示源文件所在目錄的上上級目錄,并以此類推。getAbsolutePath 方法不會做這種轉換的操作,而 getCanonicalPath 方法則會將這些特殊字符進行識別并取合適的語義。

例如:

File file = new File("..\\a.txt");
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());

輸出結果:

C:\Users\yanga\Desktop\Java\workspace2017\TestFile\..\a.txt
C:\Users\yanga\Desktop\Java\workspace2017\a.txt

前者會將「..\a.txt」作為文件路徑名稱的一部分,而后者卻能夠識別「..\a.txt」表示的是「a.txt」位于當前目錄的上級目錄中。這就是兩者最大的不同之處,適合不同的情境。

文件的屬性信息獲取

這部分的文件操作其實很簡單,無非是一些文件權限的問題,是否可讀,是否可寫,是否為隱藏文件等。下面我們具體看看這些方法:

  • public boolean canRead():該抽象的 File 實例對應的文件是否可讀
  • public boolean canWrite():該抽象的 File 實例對應的文件是否可寫
  • public boolean exists():該抽象的 File 實例對應的文件是否實際存在
  • public boolean isDirectory():該抽象的 File 實例對應的文件是否是一個目錄
  • public boolean isFile():該抽象的 File 實例對應的文件是否是一個純文件
  • public boolean isHidden():該抽象的 File 實例對應的文件是否是一個隱藏文件
  • public long length():文件內容所占的字節(jié)數

需要說明一點的是,length 方法對于純文件來說,可以正確返回該文件的字節(jié)總數,但是對于一個目錄而言,返回值將會是一個「unspecified」的數值,既不是目錄下所有文件的總字節(jié)數,也不是零,只是一個未被說明的數值,沒有意義。

文件的操作

文件的操作無外乎「增刪改查」,下面我們一起來看看。

  • public boolean createNewFile():根據抽象的 File 對象創(chuàng)建一個實際存在的磁盤文件
  • public boolean delete():刪除該 File 對象對應的磁盤文件,刪除失敗會返回 false

當然,處理上述兩個簡單的新建和刪除操作,File 類還提供了所謂「查詢」操作,這個我們要好好學習一下。例如:

public String[] list() {
 SecurityManager security = System.getSecurityManager();
 if (security != null) {
 security.checkRead(path);
 }
 if (isInvalid()) {
 return null;
 }
 return fs.list(this);
}

這個方法會檢索出當前實例所代表的目錄下所有的「純文件」和「目錄」簡單名稱集合。例如:

File file = new File("C:\\Users\\yanga\\Desktop");
String[] list = file.list();
for (String str : list){
 System.out.println(str);
}

程序的輸出結果會打印我電腦桌面目錄下所有的文件的簡單名稱,就不給大家看了。

需要注意一點,如果我們的 File 實例對應的不是一個目錄,而是一個純文件,那么 list 將返回 null。

接著,我們再看一個檢索目錄文件的方法:

 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()]);
}

這個方法其實是 list 的重載版本,它允許傳入一個過濾器用于檢索目錄時只篩選我們需要的文件及目錄。

而這個 FilenameFilter 接口的定義卻是如此簡單:

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

只需要重寫這個 accept 方法即可,list 的 for 循環(huán)每獲取一個文件或目錄就會嘗試著先調用這個過濾方法,如果通過篩選,才會將當前文件的簡單名稱添加進返回集合中。

所以這個 accept 方法的重寫就決定著哪些文件能夠通過篩選,哪些則不能。我們看個例子:

我的桌面上 test 文件夾下文件情況如下:

File file = new File("C:\\Users\\yanga\\Desktop\\test");
 String[] list = file.list(
 new FilenameFilter() {
  @Override
  public boolean accept(File dir, String name) {
  // dir 代表的當前 File 對象
  //name 是當前遍歷的文件項的簡單名稱
  if (!name.endsWith(".txt"))
   return false;
  else
   return true;
  }
 }
 );
 for (String str : list){
 System.out.println(str);
 }

這里呢,我們使用匿名內部類創(chuàng)建一個 FilenameFilter 的子類實例,然后實現了它的 accept 方法,具體的實現很簡單,過濾掉所有的目錄并取出所有純文件的簡單名稱。

最后輸出結果如下:

3.txt
4.txt

當然,File 類中還提供了兩個「變種」list 方法,例如:

  • public File[] listFiles()
  • public File[] listFiles(FilenameFilter filter)

它們不再返回目標目錄下的「純文件」和「目錄」的簡單名稱,而返回它們所對應的 File 對象,其實也沒什么,目標目錄 + 簡單名稱 即可構建出這些 File 實例了。

所以,本質上說,list 方法并不會遍歷出目標目錄下的所有文件,即目標目錄的子目錄中的文件并不會被訪問遍歷。

所以你應當思考如何完成目標目錄下所有文件的遍歷,包含一級子目錄下的深層次文件的遍歷。文末將給出答案。

接下來的兩個方法和文件夾的創(chuàng)建有關:

  • public boolean mkdir()
  • public boolean mkdirs()

兩者都是依據的當前 File 實例創(chuàng)建文件夾,關于它們的不同點,我們先看一段代碼:

File file = new File("C:\\Users\\yanga\\Desktop\\test2");
System.out.println(file.mkdir());

File file2 = new File("C:\\Users\\yanga\\Desktop\\test3\\hello");
System.out.println(file2.mkdir());

其中,test2 和 test3 在程序執(zhí)行之前都不存在。

輸出結果如下:

true
false

為什么后者創(chuàng)建失敗了?

這源于 mkdir 方法一次只能創(chuàng)建一個文件夾,倘若給定的目錄的父級或更上層目錄存在未被創(chuàng)建的目錄,那么將導致創(chuàng)建失敗。

而 mkdirs 方法就是用于解決這種情境的,它會創(chuàng)建目標路徑上所有未創(chuàng)建的目錄,看代碼:

File file3 = new File("C:\\Users\\yanga\\Desktop\\test3\\hello\\231");
System.out.println(file3.mkdirs());

即便我們 test3 文件夾就不存在,程序運行之后,test3、hello、231 這三個文件夾都會被創(chuàng)建出來。

除此之外,File 還有一類創(chuàng)建臨時文件的方法,所謂臨時文件即:運行期存在,虛擬機關閉時銷毀。大家可以自行研究,使用上還是比較簡單的,這里不再贅述了。

至此,有關 File 這個文件類型,我們大致學習了一下,想必大家都會或多或少的感覺到將純文件和目錄使用同一個類型進行表示的設計似乎有些混亂不合理。知道 jdk1.7 sun 推出了 Files 和 Path 分離了文件和目錄,我們后續(xù)文章會詳細學習一下。

文章中的所有代碼、圖片、文件都云存儲在我的 GitHub 上:

(https://github.com/SingleYam/overview_java)

大家也可以選擇通過本地下載。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • springboot使用nacos的示例詳解

    springboot使用nacos的示例詳解

    這篇文章主要介紹了springboot使用nacos的示例代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • 實例講解java定時任務

    實例講解java定時任務

    這篇文章主要介紹了實例講解java定時任務,感興趣的的朋友可以參考下
    2015-08-08
  • 詳解JAVA Spring 中的事件機制

    詳解JAVA Spring 中的事件機制

    這篇文章主要介紹了JAVA Spring 中的事件機制的相關資料,文中示例代碼非常細致,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • 淺談mybatisPlus的Ipage分頁和map參數的問題

    淺談mybatisPlus的Ipage分頁和map參數的問題

    這篇文章主要介紹了mybatisPlus的Ipage分頁和map參數的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java使用正則表達式截取重復出現的XML字符串功能示例

    Java使用正則表達式截取重復出現的XML字符串功能示例

    這篇文章主要介紹了Java使用正則表達式截取重復出現的XML字符串功能,涉及java針對xml字符串及指定格式字符串的正則匹配相關操作技巧,需要的朋友可以參考下
    2017-08-08
  • 深入了解Spring中最常用的11個擴展點

    深入了解Spring中最常用的11個擴展點

    我們一說到spring,可能第一個想到的是?IOC(控制反轉)?和?AOP(面向切面編程)。除此之外,我們在使用spring的過程中,有沒有發(fā)現它的擴展能力非常強。今天就來跟大家一起聊聊,在Spring中最常用的11個擴展點
    2022-09-09
  • Java 實現加密數據庫連接的步驟

    Java 實現加密數據庫連接的步驟

    這篇文章主要介紹了Java 實現加密數據庫連接的步驟,幫助大家更好的理解和使用Java處理數據庫,感興趣的朋友可以了解下
    2020-11-11
  • Java中String類(字符串操作)的10個常見問題和解決方法

    Java中String類(字符串操作)的10個常見問題和解決方法

    這篇文章主要介紹了Java中String類(字符串)操作的10個常見問題,需要的朋友可以參考下
    2014-04-04
  • 解決IDEA插件市場Plugins無法加載的問題

    解決IDEA插件市場Plugins無法加載的問題

    這篇文章主要介紹了解決IDEA插件市場Plugins無法加載的問題,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • 詳解SpringBoot目錄結構劃分

    詳解SpringBoot目錄結構劃分

    代碼目錄結構是一個在項目開發(fā)中非常重要的部分,本文主要介紹了詳解SpringBoot目錄結構劃分,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08

最新評論