delete():
直接删除
public boolean delete() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return false;
}
return fs.delete(this);
}
deleteOnExit():
这个方法简单说就是要求在java虚拟机结束的时候删除该文件或目录,也就是说在调用deleteOnExit方法后,File并没有被直接删除。
值得注意的一点是, JVM在删除这些调用过 deleteOnExit 方法的文件或目录的时候,是按照调用顺序的倒序进行的,也就是说最后调用deleteOnExit方法的最先删除,最先调用的最后删除。
public void deleteOnExit() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return;
}
DeleteOnExitHook.add(path); // 没有直接删除,而是将待删除文件添加到DeleteOnExitHook的待删除文件列表中。JVM结束时调用。
}
class DeleteOnExitHook {
//保存待删除文件 path 的哈希表
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() {}
//将待删除文件 path 添加到待删除哈希表中,可以重复添加。
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);
}
// JVM 结束时调用
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(); //删除文件
}
}
}