0



我正在使用 JSmooth 开发 JAVA。
我看到每次启动时都会创建一个 tmp JAR。

创建的 tmp jar 文件大约为 10 Mb。

当我退出由 JSmooth 构建的可执行 JAVA 应用程序时,
临时 jar 文件会在每次启动时保留。

我阅读了以下关于 JSmooth 的主题:
JSmooth - 退出应用程序

7.1.2.
当 java 应用程序退出时,提取的 jar 文件会发生什么?

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

Windowed 和 Console wrapper 总是更喜欢 JVM 实例化方法,这些方法允许它们在应用程序退出后删除 temp 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)是非常危险的,因为计算机可能出现故障。

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

4

2 回答 2

2

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

这意味着任何从程序中删除它们的尝试,无论是通过file.delete()还是file.deleteOnExit()将失败。这也是JSmooth出现bug的原因,也是无法删除文件的原因。

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

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

因为 Windows 没有适合命令行的 sleep 命令,所以我滥用 ping 命令在运行下一个命令之前延迟 3 秒。这个技巧在:如何在 Windows 的命令提示符中休眠 5 秒?(或 DOS)

于 2016-02-22T15:46:53.397 回答
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 对我的帮助。

于 2016-02-22T16:47:08.243 回答