File類中createNewFile方法為什麼需要丟擲異常而mkdirs不需要?
問題
在學習對硬碟檔案操作類File時我們會遇到如下的情況:
我們來建立一個新檔案:
public class FileTest {
public static void main(String[] args) {
testOfCreateNewFile();//報錯
}
public static void testOfCreateNewFile(){
File file = new File("D:\\javaspace\\study.txt");
boolean isNewFile = false;
isNewFile = file.createNewFile();//報錯
System.out.println(isNewFile);
}
編譯器一般會報錯:Unhandled exception: java.io.IOException,意思是沒有進行IO異常的處理。這裡我們很奇怪?我們的程式碼語法上是沒有錯誤的為什麼編譯不通過?我們其實忽略了方法中潛在的異常:如果路徑中的javaspace目錄不存在呢?或者說在多執行緒檔案被中途刪除了呢?所以系統會提示我們去處理或者丟擲這個異常,我的部落格裡有一篇部落格專門講了如何去處理這個異常,這裡我們簡單的寫書正確處理異常的程式碼即可:
public static void testOfCreateNewFile (){
File file = new File("D:\\javaspace_idea\\texture\\study.txt");
boolean isNewFile = false;
try {
isNewFile = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
System.out.println(isNewFile);
}
然後我們再來看看建立目錄的過程:
public class FileTest {
public static void main(String[] args) {
testOfMkdirs();
}
public static void testOfMkdirs(){
File file = new File("D:\\a\\b\\c");
boolean isMadirs;
isMadirs = file.mkdirs();
System.out.println(isMadirs);
}
這裡編譯器是可以編譯通過的,沒有要求我們對異常進行處理,那你可能問了,如果父路徑中a、b資料夾不存在的話不是類似於上述的建立檔案出現的IO異常嗎?這個問題是值得我們去深究的。
解釋
首先我們查詢一下官方的文件:
官方文件中的createNewFile方法中標註的需要丟擲異常的,但是mkdirs是沒有標註的,其實到這裡我們就可以解決這個問題了,但是我們想知道它到底為什麼不需要丟擲異常,這裡我們就需要看mkdirs方法到底是如何實現的。所以我們打開了File類中的mkdirs方法:
//File中mkdirs的實現
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {//【1】
return true;
}
File canonFile = null;
try {//【2】
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
File parent = canonFile.getParentFile();
return (parent != null && (parent.mkdirs() || parent.exists()) &&
canonFile.mkdir());//【3】
}
這裡我們不去完整解釋這個程式碼的意思,我們從三個地方來看看:首先【1】中出現了mkdir()方法,我們知道mkdir和mkdirs的區別就是s可以在父目錄不存在的情況下建立父目錄,而mkdir是不行的,這說明mkdirs和mkdir是有關係的。再來看【2】是一個對異常的處理,也許到這裡你可以大致明白為什麼mkdirs不用丟擲異常了吧,因為方法內部已經對異常進行了處理。這裡還選了第三個地方進行解釋【3】:我們奇怪為什麼mkdirs能建立父目錄,其實這裡出現的mkdir迭代已經說明問題,mkdirs中其實在父目錄不存在的時候會進行判斷,然後迭代mkdir來建立父目錄,直至它存在,所以總結下來這個方法是不需要處理異常的。