zoukankan      html  css  js  c++  java
  • FTP服务:file.delete()与file.deleteOnExit()

     file.delete()file.deleteOnExit()

    之前使用ftp下载文件的时候会用到File.createTempFil()创建临时文件存储数据,用完之后就用file.delete()与file.deleteOnExit()删除临时文件。在windows的开发环境进行测试时,临时文件会被创建在C:Users{当前电脑用户名}AppDataLocalTemp该目录下。在现场环境,临时文件则会被创建在tomcat的temp文件夹下面。最近发现现场环境中temp下面居然堆积了大量的临时文件,然后查了一下代码发现是因为用了file.deleteOnExit()

    这里得介绍一下file.delete()file.deleteOnExit()这两个删除文件方法:

    file.delete() :删除文件,删除的是创建File对象时指定与之关联创建的那个文件.这是一个立刻执行的操作

    file.deleteOnExit() : JVM进程退出的时候删除文件,通常用在临时文件的删除.这个不会立刻执行,会等到jvm进程退出的时候删除

    这里看到一个”JVM进程退出”,这是什么意思呢?百度一下得到:

    JVM的关闭意味着将停止系统中所有的任务

    按照这里的介绍,当应用关闭的时候,应该就可以把临时文件删了。然而,现场环境还是存了一大堆的临时文件没有删除。

    这时候查看一下源码:

    File.java

     1 public void deleteOnExit() {
     2     SecurityManager security = System.getSecurityManager();
     3     if (security != null) {
     4         security.checkDelete(path);
     5     }
     6     if (isInvalid()) {
     7         return;
     8     }
     9     DeleteOnExitHook.add(path);
    10 }

    DeleteOnExitHook.java

     1 package java.io;
     2 import java.util.*;
     3 import java.io.File;
     4 
     5 /**
     6  * This class holds a set of filenames to be deleted on VM exit through a shutdown hook.
     7  * A set is used both to prevent double-insertion of the same file as well as offer
     8  * quick removal.
     9  */
    10 
    11 class DeleteOnExitHook {
    12     private static LinkedHashSet<String> files = new LinkedHashSet<>();
    13     static {
    14         // DeleteOnExitHook must be the last shutdown hook to be invoked.
    15         // Application shutdown hooks may add the first file to the
    16         // delete on exit list and cause the DeleteOnExitHook to be
    17         // registered during shutdown in progress. So set the
    18         // registerShutdownInProgress parameter to true.
    19         sun.misc.SharedSecrets.getJavaLangAccess()
    20             .registerShutdownHook(2 /* Shutdown hook invocation order */,
    21                 true /* register even if shutdown in progress */,
    22                 new Runnable() {
    23                     public void run() {
    24                        runHooks();
    25                     }
    26                 }
    27         );
    28     }
    29 
    30     private DeleteOnExitHook() {}
    31 
    32     static synchronized void add(String file) {
    33         if(files == null) {
    34             // DeleteOnExitHook is running. Too late to add a file
    35             throw new IllegalStateException("Shutdown in progress");
    36         }
    37 
    38         files.add(file);
    39     }
    40 
    41     static void runHooks() {
    42         LinkedHashSet<String> theFiles;
    43 
    44         synchronized (DeleteOnExitHook.class) {
    45             theFiles = files;
    46             files = null;
    47         }
    48 
    49         ArrayList<String> toBeDeleted = new ArrayList<>(theFiles);
    50 
    51         // reverse the list to maintain previous jdk deletion order.
    52         // Last in first deleted.
    53         Collections.reverse(toBeDeleted);
    54         for (String filename : toBeDeleted) {
    55             (new File(filename)).delete();
    56         }
    57     }
    58 }

    可以看出,使用deleteOnExit方法的话不会立刻删除,而是把文件地址先保存到一个链表中。ShutdownHook正常结束的话,就会把之前存的文件地址拿出来一个一个的删掉。如果异常结束的话,那么这些临时文件就删除不了了。

    因此推断,现场环境的临时文件垃圾,是因为平时关闭应用是直接关闭窗口导致异常结束引起的。

    值得一提的是,这样使用deleteOnExit方法的话会占用大量的内存,直至JVM终止,因此建议谨慎使用。

    参考文章:

    http://www.hackerav.com/?post=80616

    https://blog.csdn.net/qq_44813090/article/details/104227356

  • 相关阅读:
    java把集合数据写入txt文档
    eclipse 启动报内存溢出的问题out of memory!
    面向对象基础知识整理
    在不同环境下MD5加密相同字符串,密文不一样的问题
    氮化镓选型
    碳化硅选型
    DSP选型
    FPGA选型
    MCU选型
    正点原子
  • 原文地址:https://www.cnblogs.com/bestlmc/p/12370755.html
Copyright © 2011-2022 走看看