NO IMAGE

本文簡單介紹File類常用的方法和一些場景。兩部分,第一部分作為介紹,第二部分給出程式碼例子。

(一)基礎介紹

(1) 定義

File類可以表示“目錄”或者“檔案”。先來看一下File類的靜態成員。

(2) 靜態成員

public static final String     pathSeparator        // 路徑分割符":"
public static final char     pathSeparatorChar      // 路徑分割符':'
public static final String     separator            // 分隔符"/"
public static final char     separatorChar          // 分隔符'/'

這裡給出了兩種符號,每一個符號有兩種型別,String和Char,通常我們都是用String。那麼為什麼要將” : “和” / “這樣表示呢,這主要還是因為Linux和Windows系統的差異造成的,為了讓程式能夠跨平臺使用,訪問目錄或者檔案不出現”No such file or directory”錯誤,就有了這種分割符號的靜態常量。打個比方,我們現在要在一個叫helloworld的目錄下建立一個test.txt檔案,那麼在Linux和Windows下的寫法分別是:

//Linux下寫法
File file = new File("/helloworld/test.txt");
//Windows下寫法
File file = new File("D:\\helloworld\\test.txt");

但是使用分隔符常量就可以合併唯一,不用再擔心程式會執行在哪一種作業系統中:

 File file = new File("D:"   File.separator   "tmp"   File.separator, "test.txt");
//或者
File file = new File("D:"   File.separator   "tmp"   File.separator   "test.txt");

不要懷疑哦,怎麼又是兩種寫法,這兩種寫法結果都是一樣,只不過是呼叫的不同的構造器而已,在(3)看一下File中的集中建構函式。

關於這個四個靜態常量再具體解釋一下:

public static final char separatorChar

與系統有關的預設名稱分隔符。此欄位被初始化為包含系統屬性 file.separator 值的第一個字元。在 UNIX 系統上,此欄位的值為 ‘/’;在 Microsoft Windows 系統上,它為 ‘\’。

public static final String separator

與系統有關的預設名稱分隔符,為了方便,它被表示為一個字串。此字串只包含一個字元,即 separatorChar。

public static final char pathSeparatorChar

與系統有關的路徑分隔符。此欄位被初始為包含系統屬性 path.separator 值的第一個字元。此字元用於分隔以路徑列表 形式給定的檔案序列中的檔名。在 UNIX 系統上,欄位為 ‘:’;在 Microsoft Windows 系統上,它為 ‘;’。

public static final String pathSeparator

與系統有關的路徑分隔符,為了方便,它被表示為一個字串。此字串只包含一個字元,即 pathSeparatorChar。

(3) 建構函式

File(File parent, String child)     //建立一個新的 File例項從父母孩子抽象路徑名和路徑名字串。  
File(String pathname)               //建立一個新的 File例項通過將給定路徑名字串轉換為抽象路徑名。  
File(String parent, String child)   //建立一個新的 File例項從一個父路徑名字串和一個孩子路徑名字串。  
File(URI uri)                       //建立一個新的 File例項通過將給定 file: URI轉換為一個抽象的路徑名。

File提供了四種構造器,可以滿足建立目錄,子目錄,多級目錄,檔案等等。

1、建立目錄的方法

現在我需要在”E:/FileTest”下建立新目錄helloworld:

方法1

File helloworld = new File("E:" File.separator "FileTest" File.separator "helloworld");
helloworld.mkdir();

方法2

URI uri = null;
try {
uri = new URI("file:/E:/FileTest/helloworld/");
} catch (URISyntaxException e) {
e.printStackTrace();
}
File helloworld = new File(uri);
helloworld.mkdir();

如果我只是需要在當前目錄下建立目錄helloworld(當前目錄指的是java程式所在的工程目錄),那麼只要寫個目錄的名字就可以了,這就是相當於寫了helloworld的相對路徑了。

方法3

File helloworld = new File("helloworld");
helloworld.mkdir();

這個目錄的完整路徑是java工程所在目錄,我的機器上是這樣的:E:\CODE\Study\FileTest\helloworld。

2、建立子目錄的方法

在工程目錄的helloworld目錄下建立子目錄sub(x):

方法1:

File sub1 = new File("helloworld", "sub1");
sub1.mkdir();

方法2:

File sub2 = new File(helloworld, "sub2");
sub2.mkdir();

方法1和方法2的作用是,在當前目錄下 “helloworlde/sub1″。它能正常執行的前提是“sub1/sub2”的父目錄“helloworld”已經存在。

方法3:

File sub3 = new File("helloworld/sub3");
sub3.mkdirs();

方法4:

File sub4 = new File("E:/CODE/Study/FileTest/helloworld/sub4");
sub4.mkdirs();

方法3和方法4不需要helloworld已經存在,也能正常執行;若“sub3/sub4”的父目路不存在,mkdirs()方法會自動建立父目錄。

方法5:

URI uri = new URI("file:/E:/CODE/Study/FileTest/helloworld/sub5"); 
File sub5 = new File(uri);
sub5.mkdirs();

3、新建檔案的方法

在工程所在的當前的helloworld目錄下建立檔案”*.txt”

方法1

    File helloworld = new File("helloworlde");    // 獲取目錄“helloworld”對應的File物件
File file1 = new File(helloworld, "1.txt");
try{
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}

方法2

try {
File file2 = new File("helloworld", "2.txt");
file2.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}

方法3

try {
File file3 = new File("E:/CODE/Study/FileTest/helloworld/3.txt");
file3.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}

方法4

try {
URI uri = new URI("file:/E:/CODE/Study/FileTest/helloworld/4.txt"); 
File file4 = new File(uri);
file4.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}

這四種方法都有一個共同的前提,那就是目錄helloworld必須要存在,否則會出現java.io.IOException: 系統找不到指定的路徑異常。只不過方法1和方法2是通過相對目錄完成建立檔案的,而方法3是通過絕對路徑,而方法4類似於3,只不過是將絕對路徑對應的uri作為引數獲得了helloworld的檔案物件。
以上就是File建構函式的介紹以及用法。

(4) File API概覽

boolean canExecute()                                            //測試應用程式是否可以執行用此抽象路徑名錶示的檔案。  
boolean canRead()                                               //測試應用程式是否可以讀取檔案用這種抽象的路徑名。  
boolean canWrite()                                              //測試應用程式是否可以修改檔案用這種抽象的路徑名。  
int compareTo(File pathname)                                    //比較兩個抽象的路徑名字母順序進行。  
boolean createNewFile()                                         //自動建立一個新的空檔案被這個抽象路徑名當且僅當一個檔案,這個名字還不存在。  
static File createTempFile(String prefix, String suffix)        //在預設臨時檔案目錄中建立一個空檔案,使用給定的字首和字尾來生成它的名字。  
static File createTempFile(String prefix, String suffix, File directory) //建立一個新的空檔案在指定的目錄中,使用給定的字首和字尾字串生成它的名字。  
boolean delete()                                                //刪除檔案或目錄用這種抽象的路徑名。  
void deleteOnExit()                                             //請求的檔案或目錄用這個抽象路徑名在虛擬機器終止時被刪除。  
boolean equals(Object obj)                                      //測試此抽象路徑名的平等與給定的物件。  
boolean exists()                                                //檢查檔案或目錄是否用這個抽象路徑名的存在。  
File getAbsoluteFile()                                          //返回此抽象路徑名的絕對形式。  
String getAbsolutePath()                                        //返回此抽象路徑名的絕對路徑名字串。  
File getCanonicalFile()                                         //返回此抽象路徑名的規範形式。  
String getCanonicalPath()                                       //返回此抽象路徑名的規範路徑名字串。  
long getFreeSpace()                                             //返回的分割槽中未分配的位元組數 named這個抽象的路徑名。  
String getName()                                                //返回的檔案或目錄的名稱用這種抽象的路徑名。  
String getParent()                                              //返回此抽象路徑名的路徑名字串的母公司或 null如果這個路徑名不名一個父目錄。  
File getParentFile()                                            //返回此抽象路徑名的抽象路徑名的母公司或 null如果路徑名不名一個父目錄。  
String getPath()                                                //將此抽象路徑名轉換為一個路徑名字串。  
long getTotalSpace()                                            //返回分割槽的大小 named這個抽象的路徑名。  
long getUsableSpace()                                           //返回的位元組數此虛擬機器分割槽可用 named這個抽象的路徑名。  
int hashCode()                                                  //計算雜湊程式碼抽象路徑名。  
boolean isAbsolute()                                            //測試此抽象路徑名是否絕對的。  
boolean isDirectory()                                           //測試檔案是否用這個抽象路徑名是一個目錄。  
boolean isFile()                                                //測試檔案是否用這個抽象路徑名是一個正常的檔案。  
boolean isHidden()                                              //測試檔案是否被這個抽象路徑名是一個隱藏檔案。  
long lastModified()                                             //返回檔案的時間用這個抽象路徑名是最後修改。  
long length()                                                   //返回檔案的長度用這種抽象的路徑名。  
String[] list()                                                 //返回一個字串陣列命名目錄中的檔案和目錄用這種抽象的路徑名。  
String[] list(FilenameFilter filter)                            //返回一個字串陣列的命名檔案和目錄用此抽象路徑名錶示的目錄中滿足指定過濾器。  
File[] listFiles()                                              //返回一個抽象路徑名陣列表示用此抽象路徑名錶示的目錄中的檔案。  
File[] listFiles(FileFilter filter)                             //返回一個陣列抽象路徑名錶示的目錄中的檔案和目錄用這個抽象路徑名滿足指定過濾器。  
File[] listFiles(FilenameFilter filter)                         //返回一個陣列抽象路徑名錶示的目錄中的檔案和目錄用這個抽象路徑名滿足指定過濾器。  
static File[] listRoots()                                       //列出可用的檔案系統根。  
boolean mkdir()                                                 //被這個抽象路徑名建立目錄。  
boolean mkdirs()                                                //由這個抽象路徑名建立目錄命名,包括任何必要的但不存在的父目錄。  
boolean renameTo(File dest)                                     //重新命名檔案用這種抽象的路徑名。  
boolean setExecutable(boolean executable)                       //一個方便的方法來設定這個抽象路徑名的所有者的執行許可權。  
boolean setExecutable(boolean executable, boolean ownerOnly)    //集所有者或每個人都對這個抽象路徑名的執行許可權。  
boolean setLastModified(long time)                              //設定檔案或目錄的最後修改時間被這抽象的路徑名。  
boolean setReadable(boolean readable)                           //一個方便的方法來設定這個抽象路徑名的所有者的讀許可權。  
boolean setReadable(boolean readable, boolean ownerOnly)        //集所有者或每個人都對這個抽象路徑名的讀許可權。  
boolean setReadOnly()                                           //標誌著檔案或目錄被這個抽象路徑名,只允許讀取操作。  
boolean setWritable(boolean writable)                           //一個方便的方法來設定這個抽象路徑名的所有者的寫許可權。  
boolean setWritable(boolean writable, boolean ownerOnly)        //集所有者或每個人都對這個抽象路徑名的寫許可權。  
Path toPath()                                                   //返回一個 java.nio.file.Path物件由這個抽象路徑。  
String toString()                                               //返回此抽象路徑名的路徑名字串。  
URI toURI()                                                     //構造一個 file: URI表示此抽象路徑名。  
URL toURL() 棄用。 這個方法不會自動轉義字元在url是非法的。建議新程式碼抽象路徑名轉換為一個URL,首先將它轉換成一個URI,通過toURI方法,然後通過URI.toURL URI轉換成一個URL的方法。

下面的第二部分就展示一下常用的API。

(二)常用方法

寫一些簡單的程式碼,假設我在”E:FileTest”目錄下進行操作,建立資料夾helloworld,建立文字檔案若干,並在helloworld資料夾中建立新資料夾及檔案。獲取檔案的名稱,路徑,修改時間等。除此之外還將說一下如何通過遞迴,獲取目錄下所有的檔案路徑資訊,這對於檔案列表的顯示是非常好用的。

package IO;
import java.io.File;
import java.io.IOException;
/**
* Created by GFC on 2017/12/6.
*/
public class TextFile {
public static void main(String[] args) throws IOException {
File helloworld = new File("E:\\FileTest\\helloworld");
File file1 = new File("E:\\FileTest\\1.txt");
File file2 = new File("E:\\FileTest\\2.txt");
helloworld.mkdir();
file1.createNewFile();
file2.createNewFile();
System.out.println("helloworld的絕對路徑: "   helloworld.getAbsolutePath());
//建立多級目錄
//在helloworld下建立sub.txt檔案
File helloworld2sub = new File("E:\\FileTest\\helloworlde2\\sub");
File helloworldsubtxt = new File("E:\\FileTest\\helloworld\\sub.txt");
helloworld2sub.mkdirs();
helloworldsubtxt.createNewFile();
//delete,exists,isDirectory測試,測試檔案2.txt
File file = new File("E:"   File.separator   "FileTest"   File.separator   "2.txt");
if (file.exists()) {
file.delete();
}
System.out.println(file.isDirectory());
System.out.println(file.isFile());
file.createNewFile();
System.out.println("###########使用File類下的list方法進行遍歷輸出############");
//普通迴圈和遞迴迴圈輸出FileTest下所有檔案及資料夾
String type = null;
String folderName = "E:"   File.separator   "FileTest";
File folder = new File(folderName);
String[] fileList = folder.list();
for (String s : fileList)
System.out.println(s);
System.out.println("###########使用File類下的listFiles方法進行遍歷輸出############");
File[] fileList2 = folder.listFiles();
for (File f : fileList2) {
System.out.println(f.getName()   "             "   (type = f.isDirectory() ? "Folder" : "File"));
//直接將File物件列印輸出是完整路徑
System.out.println(f);
}
System.out.println("###########使用遞迴方法進行遍歷輸出############");
print(folder);
}
public static void print(File file) {
if (file != null) {
if (file.isDirectory()) {
File[] fs = file.listFiles();
for (File f : fs) {
print(f);
System.out.println(file);
}
} 
}
}
}

執行結果:

helloworld的絕對路徑: E:\FileTest\helloworld
false
false
###########使用File類下的list方法進行遍歷輸出############
1.txt
2.txt
helloworld
helloworlde2
###########使用File類下的listFiles方法進行遍歷輸出############
1.txt             File
E:\FileTest\1.txt
2.txt             File
E:\FileTest\2.txt
helloworld             Folder
E:\FileTest\helloworld
helloworlde2             Folder
E:\FileTest\helloworlde2
###########使用遞迴方法進行遍歷輸出############
E:\FileTest\1.txt
E:\FileTest\2.txt
E:\FileTest\helloworld\sub.txt
E:\FileTest\helloworld
E:\FileTest\helloworlde2\sub
E:\FileTest\helloworlde2

當我們想要遍歷多級檔案目錄的時候,遞迴是一個很不錯的選擇,通過上述我們也能夠看出來File物件列印出來的是該物件的絕對路徑。這裡只測試了部分常見功能,其它功能請檢視第一部分的第四小節File類的API,每一個方法都標註了詳細的說明。

參考內容:

https://www.imooc.com/video/3621

http://www.cnblogs.com/skywang12345/p/io_08.html