退出时清洁问题

时间:2016-02-22 15:21:54

标签: java jar temp jsmooth



我正在使用JSmooth开发JAVA 我看到每次发射时都会创建一个tmp JAR
创建的tmp jar文件大约为10 Mb
当我退出由JSmooth构建的可执行JAVA应用程序时,
临时jar文件在每次启动时都会保留
我读了关于JSmooth的以下主题:
JSmooth - exit application

7.1.2。
当java应用程序退出时,解压缩的jar文件会发生什么?

只要有可能,包装器在退出时删除文件。但请注意,这并非总是可行。例如,使用JVM DLL创建的JVM实例不会干净地卸载。 Sun记录了这种行为(不称其为错误),并且没有已知的解决方法。

Windowed和Console包装器总是更喜欢JVM实例化方法,这些方法允许它们在应用程序退出后删除临时jar。请注意,不需要在exe中嵌入jar,只需将它放在可执行文件附近的文件系统上,无论是在同一目录中,还是在兄弟或父目录中,都是安全的选择。

另请注意,Windows应用程序不需要删除Windows TEMP目录中的文件,大多数应用程序只保留它们,让操作系统对其进行管理。 MS Windows的标准行为是建议用户在磁盘空间不足时删除临时文件。


我试图在出口处删除罐子:

//For matching convention, I wrote the file in a not null package
package main;

import java.io.File;

//It is an utility class, so the class is final
public final class Constants {

    //The tmp folder key
    private static final String TMP_FOLDER = "java.io.tmpdir";

    //The main class
    private static Class<?> _mainClass_ = Constants.class;

    //It is an utility class, so hide the constructor
    private Constants(){
    }

    public static void main(String[] _args) {
        //Processing
        //....
        exit();
    }

    /**@see System#exit(int)*/
    public static void exit() {
        String path_ =_mainClass_.getProtectionDomain().getCodeSource().getLocation().getPath();
        //For keeping portability OS, replace all back slashes by slashes
        path_ = new File(path_).getAbsolutePath().replace("\\", "/");

        //For keeping portability OS, replace all back slashes by slashes
        String folder_ = System.getProperty(TMP_FOLDER).replace("\\", "/");

        if (path_.startsWith(folder_)) {
            //If the jar is located in the temp folder, then delete it before exit.
            System.out.println("path: "+path_);
            System.out.println("folder: "+folder_);

            //Try remove temp jar
            new File(path_).delete();
            new File(path_).deleteOnExit();
        }
        //Exit the program
        System.exit(0);
    }
}

我的JSmooth文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<jsmoothproject>
    <JVMSearchPath>exepath</JVMSearchPath>
    <JVMSearchPath>registry</JVMSearchPath>
    <JVMSearchPath>javahome</JVMSearchPath>
    <JVMSearchPath>jrepath</JVMSearchPath>
    <JVMSearchPath>jdkpath</JVMSearchPath>
    <JVMSearchPath>jview</JVMSearchPath>
    <arguments></arguments>
    <bundledJVMPath>jre</bundledJVMPath>
    <currentDirectory>${EXECUTABLEPATH}</currentDirectory>
    <embeddedJar>false</embeddedJar>
    <executableName>Test.exe</executableName>
    <initialMemoryHeap>-1</initialMemoryHeap>
    <jarLocation>target\Test.jar</jarLocation>
    <mainClassName>main.Constants</mainClassName>
    <maximumMemoryHeap>1073741824</maximumMemoryHeap>
    <maximumVersion>1.7</maximumVersion>
    <minimumVersion>1.7</minimumVersion>
    <skeletonName>Windowed Wrapper</skeletonName>
    <skeletonProperties>
        <key>Message</key>
        <value>Java has not been found on your computer. Do you want to download it?</value>
    </skeletonProperties>
    <skeletonProperties>
        <key>URL</key>
        <value>http://www.java.com</value>
    </skeletonProperties>
    <skeletonProperties>
        <key>SingleProcess</key>
        <value>0</value>
    </skeletonProperties>
    <skeletonProperties>
        <key>SingleInstance</key>
        <value>0</value>
    </skeletonProperties>
    <skeletonProperties>
        <key>JniSmooth</key>
        <value>0</value>
    </skeletonProperties>
    <skeletonProperties>
        <key>Debug</key>
        <value>1</value>
    </skeletonProperties>
</jsmoothproject>

我认为计算机的可用空间(每次发射,可用空间减少10 Mb)非常危险 因为计算机可能出现故障。

我希望,我的问题是准确的,我不会无所事事地扰乱人们 我非常感谢能够抽出时间回答的人。

2 个答案:

答案 0 :(得分:2)

Java无法删除Windows下当前使用的文件。这是Windows的限制。

这意味着,通过file.delete()file.deleteOnExit()尝试从程序中删除它们的任何尝试都将失败。这也是JSmooth中的错误的原因,以及它无法删除文件的原因。

虽然您无法直接删除该文件,但您可以启动一个像cmd这样的辅助程序来安排在10秒左右之后删除该文件,这可以通过在退出程序时运行以下命令来完成:

new ProcessBuilder("cmd","/c","ping 127.0.0.1 && del "+filename).inheritIO().start();

由于Windows没有为命令行提供正确的睡眠命令,因此我在执行下一个命令之前滥用ping命令给出3秒的延迟。这个技巧在How to sleep for 5 seconds in Windows's Command Prompt? (or DOS)

解释

答案 1 :(得分:0)

@Ferrybig:
最后,

我删除了所有以前的tmp jar文件,
因为临时文件中的程序写入tmp jar文件是非常罕见的
此外,如果使用tmp jar文件,删除它会失败,因此在执行结束时删除是安全的
我的新代码:

//For matching convention, I wrote the file in a not null package
package main;

import java.io.File;

//It is an utility class, so the class is final
public final class Constants {

    //The tmp folder key
    private static final String TMP_FOLDER = "java.io.tmpdir";

    //The main class
    private static Class<?> _mainClass_ = Constants.class;

    //It is an utility class, so hide the constructor
    private Constants(){
    }

    public static void main(String[] _args) {
        //Processing
        //....
        exit();
    }

    /**@see System#exit(int)*/
    public static void exit() {
        String path_ =_mainClass_.getProtectionDomain().getCodeSource().getLocation().getPath();
        //For keeping portability OS, replace all back slashes by slashes
        path_ = new File(path_).getAbsolutePath().replace("\\", "/");

        //For keeping portability OS, replace all back slashes by slashes
        String folder_ = System.getProperty(TMP_FOLDER).replace("\\", "/");

        if (path_.startsWith(folder_)) {
            //If the jar is located in the temp folder, then delete all previous jars before exit.
            //Begin of my new code
            try {
                for (File f: new File(folder_).listFiles()) {
                    if (!f.getName().toLowerCase().endsWith(".jar")) {
                        continue;
                    }
                    f.delete();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //End of my new code
        }
        //Exit the program
        System.exit(0);
    }
}


我感谢Ferrybig和Marged帮助了我。