I wrote some code for my question about deleting temp files that weren't deleted on exit before and would like to get some feedback if I forgot some details or got something wrong.
private static final String PROJECTNAME = "projectname";
private static final String LOCKNAME = "lock_ThisIsAVeryLongFilenameNoOtherApplicationWillUse.lock";
private static void initTempDir(Path tempPath) throws IOException {
final Path tempFolder = Files.createTempDirectory(tempPath, PROJECTNAME);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
DeepDelete.deepDelete(tempFolder);
} catch (IOException e) {
e.printStackTrace();
}
}));
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Path lockFile = tempFolder.resolve(LOCKNAME);
try {
Files.write(lockFile, ByteBuffer.allocate(Long.BYTES).putLong(System.currentTimeMillis()).array());
} catch (IOException e) {
System.err.println("Failed to secure avaliability of temp folder, exiting!");
e.printStackTrace();
System.exit(-1);
}
}
}, 60_000, 60_000);
// Make first write manually to be sure the file has been written when
// old temp files get deleted. Otherwise, the current temp file not
// having a time stamp (yet) would be classified as old and removed.
Files.write(tempFolder.resolve(LOCKNAME),
ByteBuffer.allocate(Long.BYTES).putLong(System.currentTimeMillis()).array());
long currentTime = System.currentTimeMillis();
Files.list(tempFolder.getParent())//
.filter(Files::isDirectory)//
.filter(p -> p.getFileName().toString().startsWith(PROJECTNAME))//
.filter(p -> {
Path lock = p.resolve(LOCKNAME);
if (!Files.isRegularFile(lock))
return true;
try {
return ByteBuffer.wrap(Files.readAllBytes(lock)).getLong() < currentTime - 60_000 * 5;
} catch (IOException e) {
e.printStackTrace();
return false;
}
})//
.forEach(p -> {
try {
DeepDelete.deepDelete(p);
} catch (IOException e) {
e.printStackTrace();
}
});
}
The method takes in the path to the default temp directory and first initializes the own temp folder with the hardcoded prefix PROJECTNAME
. The folder has a file whose name is in the constant LOCKNAME
in it. Each minute, the current time is written in this file. In the end of initialization, each folder in the temp directory with the same prefix and with a lock file older than five minutes is considered a leftover from a crash and gets deleted.