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

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

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

  1. public void deleteOnExit() {

  2. SecurityManager security = System.getSecurityManager();

  3. if (security != null) {

  4. security.checkDelete(path);

  5. if (isInvalid()) {

  6. DeleteOnExitHook.add(path);

        从源码中可以看出deleteOnExit使用了DeleteOnExitHook类,这个类记录了在虚拟机关闭时需要删除的文件。源码如下:
  1. * This class holds a set of filenames to be deleted on VM exit through a shutdown hook.

  2. * A set is used both to prevent double-insertion of the same file as well as offer

  3. private static LinkedHashSet<String> files = new LinkedHashSet<>();

  4. // DeleteOnExitHook must be the last shutdown hook to be invoked.

  5. // Application shutdown hooks may add the first file to the

  6. // delete on exit list and cause the DeleteOnExitHook to be

  7. // registered during shutdown in progress. So set the

  8. // registerShutdownInProgress parameter to true.

  9. sun.misc.SharedSecrets.getJavaLangAccess()

  10. .registerShutdownHook(2 /* Shutdown hook invocation order */,

  11. true /* register even if shutdown in progress */,

  12. new Runnable() {

  13. public void run() {

  14. runHooks();

  15. private DeleteOnExitHook() {}

  16. static synchronized void add(String file) {

  17. if(files == null) {

  18. // DeleteOnExitHook is running. Too late to add a file

  19. throw new IllegalStateException("Shutdown in progress");

  20. static void runHooks() {

  21. LinkedHashSet<String> theFiles;

  22. synchronized (DeleteOnExitHook.class) {

  23. theFiles = files;

  24. files = null;

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

  26. // reverse the list to maintain previous jdk deletion order.

  27. // Last in first deleted.

  28. Collections.reverse(toBeDeleted);

  29. for (String filename : toBeDeleted) {

  30. (new File(filename)).delete();

        DeleteOnExitHook使用了java的关闭钩子,通过LinkedHashSet保存要删除的文件路径,并且利用Set的特性来防止插入重复的路径,在删除时会反转顺序,按照与添加时相反的顺序进行删除。
        delete立即删除文件,通常删除文件调用此方法即可,如果文件是被当作临时存储被多个方法或对象引用,程序结束后需要关闭,此时只要在文件创建时使用deleteOnExit方法,就可以在程序结束时删除文件,而不需要在多个地方进行文件删除的动作。但是使用deleteOnExit删除文件时,如果失败是看不到失败原因的。
        另外要注意的是,如果文件的流没有关闭的话,文件是无法删除的。

本文使用 文章同步助手 同步

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容