2010-02-12

Files Delete Processing

怎麼 Java 提供了 File.mkdirs() 函式卻沒有對應的 File.rmdirs() 函式可用,應該要有的不是嗎?這麼理所當然的想法,對於想要刪除整串子目錄的程式員,一時之間還真以為是自己找不到可用的 API 函式庫。

讓我們分享一個可以刪除整個子目錄及檔案的實作。

這程式是以遞回的方式在運作,執行這個方法後有幾個特性需要注意:
  • 某個子目錄如果被鎖定,將造成上層目錄無法被移除,但資料夾內的檔案仍然會被刪除。
  • 如果沒有刪除權限將會丟出 SecurityException 錯誤。
程式碼如下:
import java.io.File;

public void deleteAll(String filename) {
    deleteAll(new File(filename));
}

public void deleteAll(File file) {
    if (file == null || !file.exists())
        return;
    if (file.isDirectory()) {
        File[] list = file.listFiles();
        if (list != null) {
            for (File t : list) {
                deleteAll(t);
            }
        }
    }
    file.delete();
}


Delete Thread
我們試著擴充這個用途,將它設計成一個執行緒類別,並刻意讓類別層級同步化,強化後的優點如下:
  • 將檔案讀寫動作以獨立執行緒的方式在背景執行。
  • 強迫多行緒依序執行,防止檔案系統過度忙錄。
程式碼如下:
DeleteFilesThread.java
import java.io.File;

public class DeleteFilesThread extends Thread {
    private File target = null;

    public DeleteFilesThread(File file) {
        this.target = file;
    }

    public void run() {
        synchronized (DeleteFilesThread.class) {
            deleteAll(target);
        }
    }

    private void deleteAll(File file) {
        if (file == null || !file.exists()) return;
        if (file.isDirectory()) {
            File[] list = file.listFiles();
            if (list != null) {
                for (File t : list) {
                    deleteAll(t);
                }
            }
        }
        file.delete();
    }

    public static void main(String[] args) {
        Thread t = new DeleteFilesThread(new File("/usr/temp/"));
        t.start();
    }
}

類別內的 main(){...} 方法主要是作展示用途,實務上可將它移除。

沒有留言: