我正在使用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)非常危险 因为计算机可能出现故障。
我希望,我的问题是准确的,我不会无所事事地扰乱人们 我非常感谢能够抽出时间回答的人。
答案 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帮助了我。