如何保证文件在一段时间后自动删除?

5

当用户上传图片后,我必须将其存储几分钟,直到用户确认并将其存储在数据库中。

因此,我想创建一个临时文件并使用它来显示预览。

但我必须确保如果用户不再交互,文件将在一段时间后被删除。

我找到了这篇关于临时文件如何自动删除的文章https://softwarecave.org/2014/02/05/create-temporary-files-and-directories-using-java-nio2/

但是,如果我理解正确,deleteOnExit 和 ShutdownHook 将在虚拟机关闭后调用,因此,如果我的应用程序在线上运行很长时间,并且这些文件永远不会被删除,DELETE_ON_EXIT 选项将在调用 close 方法时删除文件,因此如果我从未调用 close 方法,因为用户没有执行任何操作,则该文件也永远不会被删除。是这样吗?

那么...是否有任何方法可以保证文件在一段时间后自动删除?

我考虑创建一个带有 deleteOnExit 和 DELETE_ON_CLOSE 选项的 File,并添加到一个带有“超时”的线程中,在超时后检查文件是否仍存在并进行删除,但我不知道是否存在更好的方法。

谢谢。

更新

基于最佳答案,我使用 Kotlin 开发了一个项目,将此行为添加到 java.util.File 中。

https://github.com/vinicius-rob-cunha/kotlin-auto-delete-file

2个回答

5
我认为使用jvm关闭钩子函数的方法不够可靠,也似乎不是你要寻找的方法。我建议创建一个类,其中包含你想要计划删除的文件的映射,并具有回调函数,可以在调用时延迟删除时间:
private Map<Path, ScheduledFuture> futures = new HashMap<>();

private ScheduledExecutorService executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());

private static final TimeUnit UNITS = TimeUnit.SECONDS; // your time unit

public void scheduleForDeletion(Path path, long delay) {
    ScheduledFuture future = executor.schedule(() -> {
        try {
            Files.delete(path);
        } catch (IOException e) {
            // failed to delete
        }
    }, delay, UNITS);

    futures.put(path, future);
}

public void onFileAccess(Path path) {
    ScheduledFuture future = futures.get(path);
    if (future != null) {

        boolean result = future.cancel(false);
        if (result) {
            // reschedule the task
            futures.remove(path);
            scheduleForDeletion(path, future.getDelay(UNITS));
        } else {
            // too late, task was already running
        }
    }
}

我真的很喜欢这种方法,我之前不知道有这些执行器。只有一个问题,似乎计时器也可以完成工作,但它们之间有什么区别呢? - Vinicius Cunha
@ViniciusCunha 请查看https://dev59.com/-HRC5IYBdhLWcg3wG9Jb,了解更多信息。 - dev4Fun
感谢您的回答和解释,我会使用SingleThread,因为我只需要删除文件。 - Vinicius Cunha
getDelay返回剩余时间,因此这个重新调度不起作用。 - Vinicius Cunha
谢谢,根据您的回答,我使用 Kotlin 开发了一个项目,以将此功能添加到 java.util.File 中。https://github.com/vinicius-rob-cunha/kotlin-auto-delete-file - Vinicius Cunha

0
你可以使用Timer()类。它基本上允许你指定一个带有特定延迟和TimerTask的计时器。当延迟结束后,计时器会执行TimerTask并运行你的代码。你只需要以编程方式设置TimerTask的文件路径。
这里是计时器文档

你在使用Timer()是更好的选择,参考TIMER VS THREAD是正确的。但它只是在可读性和cancel()实现方面更好。无论如何,感谢您的评论。 - Kwang-Chun Kang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接