Reputation: 6667
Given a bunch of tmp directories and tmp files like this:
/tmp/garbagedir1/
/tmp/garbagedir2/
/tmp/garbagedir3/
/tmp/deleteme.txt
/tmp/deleteme.log
In Linux, we can execute one simple shell command to recursively force delete all of these:
$ rm -rf /tmp/garbagedir* /tmp/deleteme*
All of the above files and directories are deleted, including all the files that may be in the directories. All other files in the /tmp directory are not touched.
There are many ways to do this in Java, but what is the simplest way that does not involve lots of Java style boilerplate code and still be platform independent?
Upvotes: 2
Views: 5232
Reputation: 31648
Note, I haven't tested this code so don't try it first on anything important!
You can use the Java NIO2 SimpleFileVisitor to recursviely walk thru directories and their children. First we create a new FileVisitor that will delete all files that it sees and then delete the empty directories once all its children have been deleted.
FileVisitor recursiveDeleteVisitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
System.out.println("Deleting file: " + file);
Files.delete(file);
return CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException exc) throws IOException {
System.out.println("Deleting dir: " + dir);
if (exc == null) {
Files.delete(dir);
return CONTINUE;
} else {
throw exc;
}
}
};
This might count as boiler plate, but you would only have to write the FileVisitor
instance once and then you can re-use it as part of a utility class. I'm not sure why something like this isn't included in the JDK.
Anyway, once you have that, then iterate over the children of /tmp
and recursively delete any directories that match:
File root = new File("/tmp");
for(File child : root.listFiles()){
//optionally use Pattern class for regex
if(child.getName().startsWith("garbagedir")){
Files.walkFileTree(child.toPath(), recursiveDeleteVisitor);
}
}
EDIT
User fge pointed out that Java 7 has a Files.newDirectoryStream()
method that will return a DirectoryStream
object that can be used to iterate over the children instead of using the old File.listFiles()
which returns an array which means all the objects are created in memory before iteration. This could save you from memory problems if you have lots of files. You can even use the globbing pattern as a 2nd String argument.
Path root = Paths.get("/tmp");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(root, "garbagedir*")) {
for (Path entry: stream) {
Files.walkFileTree(child.toPath(), recursiveDeleteVisitor);
}
}
Upvotes: 1
Reputation: 121790
The new file API has all the tools you need:
FileVisitor
interface which you can use to perform recursive file deletion (see here for an example).Feel free to salvage the recursive deletion example, and note that it can be improved. In particular, this one will stop at the first deletion error, but it is trivial to modify so that it continues in this case instead.
Upvotes: 1
Reputation: 6954
you may use the FileUtils class of Apache Commons IO; with it you can do something like that:
FileUtils.forceDelete(new File("/home/test"));
Links to the documentation: http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html
Hope it helps
Angelo
Upvotes: 2