The file won't be deleted automatically. See File.createTempFile:
This method provides only part of a temporary-file facility. To arrange for a file created by this method to be deleted automatically, use the
deleteOnExit()method.
So you have to explicitly call File.deleteOnExit():
Answer from Kai on Stack OverflowRequests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.
The file won't be deleted automatically. See File.createTempFile:
This method provides only part of a temporary-file facility. To arrange for a file created by this method to be deleted automatically, use the
deleteOnExit()method.
So you have to explicitly call File.deleteOnExit():
Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.
As the other answers note, temporary files created with File.createTempFile() will not be deleted automatically unless you explicitly request it.
The generic, portable way to do this is to call .deleteOnExit() on the File object, which will schedule the file for deletion when the JVM terminates. A slight disadvantage of this method, however, is that it only works if the VM terminates normally; on an abnormal termination (i.e. a VM crash or forced termination of the VM process), the file might remain undeleted.
On Unix-like systems (such as Linux), it's actually possible to obtain a somewhat more reliable solution by deleting the temporary file immediately after opening it. This works because Unix filesystems allow a file to be deleted (unlinked, to be precise) while it's still held open by one or more processes. Such files can be accessed normally through the open filehandle, and the space they occupy on disk will only be reclaimed by the OS after the last process holding an open handle to the file exits.
So here's the most reliable and portable way I know to ensure that a temporary file will be properly deleted after the program exits:
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
public class TempFileTest
{
public static void main(String[] args)
{
try {
// create a temp file
File temp = File.createTempFile("tempfiletest", ".tmp");
String path = temp.getAbsolutePath();
System.err.println("Temp file created: " + path);
// open a handle to it
RandomAccessFile fh = new RandomAccessFile (temp, "rw");
System.err.println("Temp file opened for random access.");
// try to delete the file immediately
boolean deleted = false;
try {
deleted = temp.delete();
} catch (SecurityException e) {
// ignore
}
// else delete the file when the program ends
if (deleted) {
System.err.println("Temp file deleted.");
} else {
temp.deleteOnExit();
System.err.println("Temp file scheduled for deletion.");
}
try {
// test writing data to the file
String str = "A quick brown fox jumps over the lazy dog.";
fh.writeUTF(str);
System.err.println("Wrote: " + str);
// test reading the data back from the file
fh.seek(0);
String out = fh.readUTF();
System.err.println("Read: " + out);
} finally {
// close the file
fh.close();
System.err.println("Temp file closed.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
On a Unix-like system, running this should produce something like the following output:
Temp file created: /tmp/tempfiletest587200103465311579.tmp
Temp file opened for random access.
Temp file deleted.
Wrote: A quick brown fox jumps over the lazy dog.
Read: A quick brown fox jumps over the lazy dog.
Temp file closed.
Whereas on Windows, the output looks slightly different:
Temp file created: C:\DOCUME~1\User\LOCALS~1\Temp\tempfiletest5547070005699628548.tmp
Temp file opened for random access.
Temp file scheduled for deletion.
Wrote: A quick brown fox jumps over the lazy dog.
Read: A quick brown fox jumps over the lazy dog.
Temp file closed.
In either case, however, the temp file should not remain on the disk after the program has ended.
PS. While testing this code on Windows, I observed a rather surprising fact: apparently, merely leaving the temp file unclosed is enough to keep it from being deleted. Of course, this also means that any crash that happens while the temp file is in use will cause it to be left undeleted, which is exactly what we're trying to avoid here.
AFAIK, the only way to avoid this is to ensure that the temp file always gets closed using a finally block. Of course, then you could just as well delete the file in the same finally block too. I'm not sure what, if anything, using .deleteOnExit() would actually gain you over that.
Add the following code (after you have done your operations with the file):
buffout.close();
fileoutput.close();
temp.delete();
As long as some stream on the file is open, it is locked (at least on the windows-implementation of the JVM). So it cannot be deleted.
It is good practice always to check if all opened streams get closed again after usage, because this is a bad memory-leak-situation. Your application can even eat up all available file-handles, that can lead to an unusable system.
There's a bug saying that if the file is open by filewriter or anything, it won't be deleted. On windows. Check if you close your file writers.
Another workaround would be installing a ShutdownHook which would manually delete the file.
Temporary directories created by Files.createTempDirectory() are not deleted upon system exit (JVM termination), unless you configure them to do so:
A shutdown-hook, or the
File.deleteOnExit()mechanism may be used to delete the directory automatically.
Meaning you could call:
Path tmp = Files.createTempDirectory(null);
tmp.toFile().deleteOnExit();
However you cannot delete a directory unless it's empty, as document by File.delete():
Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted.
So we need to get a bit fancier if you want the directory and its contents deleted. You can recursively register a directory and its children for deletion like so:
public static void recursiveDeleteOnExit(Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
@SuppressWarnings("unused") BasicFileAttributes attrs) {
file.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
@SuppressWarnings("unused") BasicFileAttributes attrs) {
dir.toFile().deleteOnExit();
return FileVisitResult.CONTINUE;
}
});
}
Take note however, this registers all currently existing files for deletion - if after calling this method you create new files, they and their parent directories will not be deleted per the documented behavior of File.delete().
If you want to delete a directory upon exit, regardless of the contents of said directory, you can use a shutdown-hook in an almost identical manner:
public static void recursiveDeleteOnShutdownHook(final Path path) {
Runtime.getRuntime().addShutdownHook(new Thread(
new Runnable() {
@Override
public void run() {
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
@SuppressWarnings("unused") BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e)
throws IOException {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
// directory iteration failed
throw e;
}
});
} catch (IOException e) {
throw new RuntimeException("Failed to delete "+path, e);
}
}}));
}
Note however that calling this repeatedly registers a new shutdown thread each time, which could potentially cause problems at scale. File.deleteOnExit() stores a set of registered files, and deletes all of them in one shutdown hook. If you need to delete many directories in this manner, you'd want to implement something similar.
As per the API, no it doesn't, you need to manually remove the directory, using file.deleteOnExit() method.
As with the createTempFile methods, this method is only part of a temporary-file facility. A shutdown-hook, or the File.deleteOnExit() mechanism may be used to delete the directory automatically.
Short Answer
You can't delete arbitrary files in Java NIO, but you can use the StandardOpenOption.DELETE_ON_CLOSE when opening a new stream, which will delete the file as soon as the stream closes, either by calling .close() (including from a try-with-resources statement) or the JVM terminating. For instance:
Files.newOutputStream(Paths.get("Foo.tmp"), StandardOpenOption.DELETE_ON_CLOSE);
Long Answer
After a great deal of digging around, I found that Java NIO does have a way to delete on exit, but it approaches it in a different way that Java I/O.
First off, the Javadoc for Files.createTempFile() describes three ways to delete files:
Where used as a work files [sic], the resulting file may be opened using the
DELETE_ON_CLOSEoption so that the file is deleted when the appropriate close method is invoked. Alternatively, a shutdown-hook, or theFile.deleteOnExit()mechanism may be used to delete the file automatically.
The last choice, File.deleteOnExit() is of course a Java I/O method, which we are trying to avoid. A shutdown-hook is what is happening behind the scenes when you call the aforementioned method. But the DELETE_ON_CLOSE option is pure Java NIO.
Rather than deleting arbitrary files, Java NIO assumes that you are only interested in deleting files that you are actually opening. Therefore, methods that create a new stream such as Files.newOutputStream() can optionally take several OpenOptions, where you can input StandardOpenOption.DELETE_ON_CLOSE. What that does is delete the file as soon as the stream is closed (either by a call to .close() or the JVM exiting).
For instance:
Files.newOutputStream(Paths.get("Foo.tmp"), StandardOpenOption.DELETE_ON_CLOSE);
...will delete the file associated with the stream when the stream is closed, either from an explicit call to .close(), the stream being closed as part of a try-with-resources statement, or the JVM terminating.
Update: On some operating systems such as Linux, StandardOpenOption.DELETE_ON_CLOSE deletes as soon as the OutputStream is created. If all you need is one OutputStream, that may still be okay. See DELETE_ON_CLOSE deletes files before close on Linux for more info.
So Java NIO adds new functionality over Java I/O in that you can delete a file when closing a stream. If that's a good enough alternative to deleting during JVM exit, you can do it in pure Java NIO. If not, you'll have to rely on Java I/O's File.deleteOnExit() or a shutdown-hook to delete the file.
Behind the scenes, File.deleteOnExit() will just create a shutdown hook via Runtime.addShutdownHook().
Then, you can do the same thing with NIO:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
Path path = ...;
Files.delete(path);
}
});
Delete the files in onDestroy if isChangingConfigurations() is false or isFinishing is true. Example:
@Override protected void onDestroy() {
super.onDestroy();
if(!isChangingConfigurations()) {
deleteTempFiles(getCacheDir());
}
}
private boolean deleteTempFiles(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
deleteTempFiles(f);
} else {
f.delete();
}
}
}
}
return file.delete();
}
call the deleteOnExit() method!
Or
call the delete() method in the onStop() of your activity.
Edit:
It might be better if you called delete() in onDestroy() to insure that your code works even if app is destroyed by system.