有没有在Java应用程序内部创建临时目录的标准可靠方法? Java的问题数据库中有一个条目,注释中包含一些代码,但是我想知道在一个常用的库(Apache Commons等)中是否找到标准解决方案?
#1楼
这是我决定为自己的代码执行的操作:
/**
* Create a new temporary directory. Use something like
* {@link #recursiveDelete(File)} to clean this directory up since it isn't
* deleted automatically
* @return the new directory
* @throws IOException if there is an error creating the temporary directory
*/
public static File createTempDir() throws IOException
{
final File sysTempDir = new File(System.getProperty("java.io.tmpdir"));
File newTempDir;
final int maxAttempts = 9;
int attemptCount = 0;
do
{
attemptCount++;
if(attemptCount > maxAttempts)
{
throw new IOException(
"The highly improbable has occurred! Failed to " +
"create a unique temporary directory after " +
maxAttempts + " attempts.");
}
String dirName = UUID.randomUUID().toString();
newTempDir = new File(sysTempDir, dirName);
} while(newTempDir.exists());
if(newTempDir.mkdirs())
{
return newTempDir;
}
else
{
throw new IOException(
"Failed to create temp dir named " +
newTempDir.getAbsolutePath());
}
}
/**
* Recursively delete file or directory
* @param fileOrDir
* the file or dir to delete
* @return
* true iff all files are successfully deleted
*/
public static boolean recursiveDelete(File fileOrDir)
{
if(fileOrDir.isDirectory())
{
// recursively delete contents
for(File innerFile: fileOrDir.listFiles())
{
if(!FileUtilities.recursiveDelete(innerFile))
{
return false;
}
}
}
return fileOrDir.delete();
}
#2楼
我遇到了同样的问题,所以这只是对那些有兴趣的人的另一个答案,它与上述之一相似:
public static final String tempDir = System.getProperty("java.io.tmpdir")+"tmp"+System.nanoTime();
static {
File f = new File(tempDir);
if(!f.exists())
f.mkdir();
}
对于我的应用程序,我决定添加一个选项来清除退出时的温度 ,因此我添加了一个关闭挂钩:
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
//stackless deletion
String root = MainWindow.tempDir;
Stack<String> dirStack = new Stack<String>();
dirStack.push(root);
while(!dirStack.empty()) {
String dir = dirStack.pop();
File f = new File(dir);
if(f.listFiles().length==0)
f.delete();
else {
dirStack.push(dir);
for(File ff: f.listFiles()) {
if(ff.isFile())
ff.delete();
else if(ff.isDirectory())
dirStack.push(ff.getPath());
}
}
}
}
});
该方法在删除temp之前先删除所有子目录和文件,而不使用调用栈(这是完全可选的,此时您可以使用递归进行此操作),但是我想保持安全。
#3楼
即使以后显式删除它,也不要使用deleteOnExit()
。
谷歌“ deleteonexit”以获得更多信息,但是问题的要点是:
deleteOnExit()
仅在正常JVM关闭时删除,而不会崩溃或杀死JVM进程。deleteOnExit()
仅在JVM关闭时删除-对于长时间运行的服务器进程来说不好,因为:- 最
deleteOnExit()
消耗每个临时文件条目的内存。 如果您的进程运行了几个月,或者在很短的时间内创建了许多临时文件,则您将消耗内存,并且在JVM关闭之前永远不要释放内存。
#4楼
正如您在其他答案中看到的那样,没有标准的方法出现。 因此,您已经提到了Apache Commons,我提出了使用Apache Commons IO中的 FileUtils的以下方法:
/**
* Creates a temporary subdirectory in the standard temporary directory.
* This will be automatically deleted upon exit.
*
* @param prefix
* the prefix used to create the directory, completed by a
* current timestamp. Use for instance your application's name
* @return the directory
*/
public static File createTempDirectory(String prefix) {
final File tmp = new File(FileUtils.getTempDirectory().getAbsolutePath()
+ "/" + prefix + System.currentTimeMillis());
tmp.mkdir();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
FileUtils.deleteDirectory(tmp);
} catch (IOException e) {
e.printStackTrace();
}
}
});
return tmp;
}
这是首选,因为apache commons是最接近要求的“标准”的库,并且可与JDK 7和更早版本一起使用。 这还会返回一个“旧” File实例(基于流),而不是一个“ new” Path实例(基于缓冲区,这是JDK7的getTemporaryDirectory()方法的结果)->因此,它返回大多数人在需要时他们想创建一个临时目录。