File类的两个方法delete和deleteOnExit的作用都是删除文件,但两者是有差别的。
delete立即删除文件,通常删除文件调用此方法即可,如果文件是被当作临时存储被多个方法或对象引用,程序结束后需要关闭,此时只要在文件创建时使用deleteOnExit方法,就可以在程序结束时删除文件,而不需要在多个地方进行文件删除的动作。但是使用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删除文件时,如果失败是看不到失败原因的。
另外要注意的是,如果文件的流没有关闭的话,文件是无法删除的。
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#csdnc-thumbsup"></use>
</svg><span class="name">点赞</span>
<span class="count"></span>
</a></li>
<li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-Collection-G"></use>
</svg><span class="name">收藏</span></a></li>
<li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-fenxiang"></use>
</svg>分享</a></li>
<!--打赏开始-->
<!--打赏结束-->
<li class="tool-item tool-more">
<a>
<svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
</a>
<ul class="more-box">
<li class="item"><a class="article-report">文章举报</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="person-messagebox">
<div class="left-message"><a href="https://blog.csdn.net/asty9000">
<img src="https://profile.csdnimg.cn/E/F/8/3_asty9000" class="avatar_pic" username="asty9000">
<img src="https://g.csdnimg.cn/static/user-reg-year/2x/12.png" class="user-years">
</a></div>
<div class="middle-message">
<div class="title"><span class="tit"><a href="https://blog.csdn.net/asty9000" data-report-click="{"mod":"popu_379"}" target="_blank">_荣耀之路_</a></span>
</div>
<div class="text"><span>发布了596 篇原创文章</span> · <span>获赞 75</span> · <span>访问量 45万+</span></div>
</div>
<div class="right-message">
<a href="https://bbs.csdn.net/topics/395526281" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-messageboard">他的留言板
</a>
<a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a>
</div>
</div>
</div>
File类的两个方法delete和deleteOnExit的作用都是删除文件,但两者是有差别的。
delete立即删除文件,通常删除文件调用此方法即可,如果文件是被当作临时存储被多个方法或对象引用,程序结束后需要关闭,此时只要在文件创建时使用deleteOnExit方法,就可以在程序结束时删除文件,而不需要在多个地方进行文件删除的动作。但是使用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删除文件时,如果失败是看不到失败原因的。
另外要注意的是,如果文件的流没有关闭的话,文件是无法删除的。
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#csdnc-thumbsup"></use>
</svg><span class="name">点赞</span>
<span class="count"></span>
</a></li>
<li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-Collection-G"></use>
</svg><span class="name">收藏</span></a></li>
<li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-fenxiang"></use>
</svg>分享</a></li>
<!--打赏开始-->
<!--打赏结束-->
<li class="tool-item tool-more">
<a>
<svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
</a>
<ul class="more-box">
<li class="item"><a class="article-report">文章举报</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="person-messagebox">
<div class="left-message"><a href="https://blog.csdn.net/asty9000">
<img src="https://profile.csdnimg.cn/E/F/8/3_asty9000" class="avatar_pic" username="asty9000">
<img src="https://g.csdnimg.cn/static/user-reg-year/2x/12.png" class="user-years">
</a></div>
<div class="middle-message">
<div class="title"><span class="tit"><a href="https://blog.csdn.net/asty9000" data-report-click="{"mod":"popu_379"}" target="_blank">_荣耀之路_</a></span>
</div>
<div class="text"><span>发布了596 篇原创文章</span> · <span>获赞 75</span> · <span>访问量 45万+</span></div>
</div>
<div class="right-message">
<a href="https://bbs.csdn.net/topics/395526281" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-messageboard">他的留言板
</a>
<a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a>
</div>
</div>
</div>