file.delete()与file.deleteOnExit()的区别

        File类的两个方法delete和deleteOnExit的作用都是删除文件,但两者是有差别的。

        delete:删除File对象表示的文件或目录,如果表示的是目录,需要保证目录是空的,否则无法删除。若成功删除返回true,否则返回false。
        deleteOnExit:当虚拟机终止时,删除File对象表示的文件或目录,如果表示的是目录,需要保证目录是空的,否则无法删除,无返回值。
        可以看出两个方法的区别是,delete是立即执行删除,而deleteOnExit是程序退出虚拟机时才会删除。重点关注deleteOnExit方法,源码如下:

public void deleteOnExit() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkDelete(path);
        }
        if (isInvalid()) {
            return;
        }
        DeleteOnExitHook.add(path);
    }
        从源码中可以看出deleteOnExit使用了DeleteOnExitHook类,这个类记录了在虚拟机关闭时需要删除的文件。源码如下:
package java.io;

import java.util.*;
import java.io.File;

/**
 * This class holds a set of filenames to be deleted on VM exit through a shutdown hook.
 * A set is used both to prevent double-insertion of the same file as well as offer
 * quick removal.
 */

class DeleteOnExitHook {
    private static LinkedHashSet<String> files = new LinkedHashSet<>();
    static {
        // DeleteOnExitHook must be the last shutdown hook to be invoked.
        // Application shutdown hooks may add the first file to the
        // delete on exit list and cause the DeleteOnExitHook to be
        // registered during shutdown in progress. So set the
        // registerShutdownInProgress parameter to true.
        sun.misc.SharedSecrets.getJavaLangAccess()
            .registerShutdownHook(2 /* Shutdown hook invocation order */,
                true /* register even if shutdown in progress */,
                new Runnable() {
                    public void run() {
                       runHooks();
                    }
                }
        );
    }

    private DeleteOnExitHook() {}

    static synchronized void add(String file) {
        if(files == null) {
            // DeleteOnExitHook is running. Too late to add a file
            throw new IllegalStateException("Shutdown in progress");
        }

        files.add(file);
    }

    static void runHooks() {
        LinkedHashSet<String> theFiles;

        synchronized (DeleteOnExitHook.class) {
            theFiles = files;
            files = null;
        }

        ArrayList<String> toBeDeleted = new ArrayList<>(theFiles);

        // reverse the list to maintain previous jdk deletion order.
        // Last in first deleted.
        Collections.reverse(toBeDeleted);
        for (String filename : toBeDeleted) {
            (new File(filename)).delete();
        }
    }
}
        DeleteOnExitHook使用了java的关闭钩子,通过LinkedHashSet保存要删除的文件路径,并且利用Set的特性来防止插入重复的路径,在删除时会反转顺序,按照与添加时相反的顺序进行删除。
        delete立即删除文件,通常删除文件调用此方法即可,如果文件是被当作临时存储被多个方法或对象引用,程序结束后需要关闭,此时只要在文件创建时使用deleteOnExit方法,就可以在程序结束时删除文件,而不需要在多个地方进行文件删除的动作。但是使用deleteOnExit删除文件时,如果失败是看不到失败原因的。
        另外要注意的是,如果文件的流没有关闭的话,文件是无法删除的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值