1. 程式人生 > >File類中createNewFile方法為什麼需要丟擲異常而mkdirs不需要?

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異常嗎?這個問題是值得我們去深究的。

解釋

首先我們查詢一下官方的文件:
CNF
MKD
官方文件中的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來建立父目錄,直至它存在,所以總結下來這個方法是不需要處理異常的。