如何使用垃圾收集删除文件?

时间:2009-06-29 07:44:50

标签: java temporary-files garbage-collection

您好我在java中使用了很多临时文件,我的问题是它们不会被删除。

无需实施我自己的临时文件管理处理(不是很难,我授予你但是我很懒,加上很多事情要做,如果我可以保存重新发明轮子,那就更好了)有没有办法确保磁盘上的临时文件将以相当规律的方式被删除。

1 - 使用File tmp = File.createTempFile(),确定我可以说tmp.deleteOnExit()但是如果事物在服务中运行它退出的唯一方式是它崩溃(很少发生),或者系统崩溃(比如当驱动器完全充满临时文件并翻倒集群时......哎呀!)

理想情况下,垃圾收集器会在某个时刻收集创建的实例,并且由于应用程序中有很多空闲时间,如果GC可以完成它的清理并实际删除,那就太花哨了当从内存中取消引用该实例时,该文件也在磁盘上。

我现在看到的唯一方法是重载File类并添加一个finalized方法......如果我这样做,那么可以选择我自己的临时文件管理器!

长话短说,我是否可以使用垃圾收集器来清理系统资源(即文件)?


谢谢大家的回答。我接受了Christoffer,因为它是最简单的实现,也是我最终做的事情。

我想,经过这么多年的清理,让我忘记了基本的家务管理,但我在C ++的好日子里做了很多努力。

7 个答案:

答案 0 :(得分:3)

当然可以。问题是你是否真的想:)

我实际上在野外遇到过这个问题;正如您所注意到的,在运行服务而不是应用程序时,使用deleteOnExit()清除临时文件是没用的。我发现最稳定的解决方案是重构程序流,以便在每个任务的基础上创建临时文件,并在不再需要时明确删除。

如果您以任何其他方式执行此操作,即如果程序无法断定在执行期间是否应保留或丢弃临时文件,则可能存在设计问题。在一些管理器工具中包装文件只会推迟“真正的”解决方案;)

答案 1 :(得分:2)

您可能需要查看PhantomReference

  

幻像引用对象,它们在收集器确定可以以其他方式回收它们之后排队。幻像引用最常用于以比Java终结机制更灵活的方式调度预先清理操作。

答案 2 :(得分:2)

当你的课程被摧毁时,依靠一个事件来解雇并不是万无一失的,并且可能会留下文件。

我认为实现临时文件清理的最简单,最可靠的方法如下:

  • 编写一个事件处理程序,用于程序关闭时清理您在当前会话期间打开的所有文件。
  • 编写一个程序启动时运行的程序,删除此文件夹中超过24小时的所有临时文件。

使用这种方法,您不必担心程序因某种原因崩溃并留下临时文件,您也不必担心程序会删除仍在使用的文件。

答案 3 :(得分:1)

垃圾收集是此类信息处理的错误命名空间。

以下几点应足以处理临时文件。

  1. 在不再使用该文件后,应该尝试直接删除该文件。 finalize块可以处理这个问题。

  2. 您应该使用DeleteOnExit。

  3. 您可以在特殊临时目录中创建临时文件。启动和关闭应用程序时可以删除此临时目录,以确保应用程序关闭后不存在临时文件。

答案 4 :(得分:1)

垃圾收集器对这些东西没用。它专为内存管理而设计,可能有许多缺点。

  • 在文件不再使用后,您的对象可能会被收集很长时间。
  • 根本无法保证收集您的物品。

如果Java以大堆大小启动,这两件事情都经常发生 - 这在服务器端并不罕见。

在您的程序中的某个时刻,您必须关闭该文件上的Streams(否则您将占用系统文件句柄,这会使系统无法使用,我已经这样做了)。在关闭流时,您还可以删除关联的文件。这是最干净的方式。

答案 5 :(得分:0)

那么你可以为一个文件做一个包装器,当这个对象被垃圾收集时,使用finalizer来删除你的文件。

但终结者不会以任何可预测的方式被召唤,所以我根本不会建议这样做。

答案 6 :(得分:0)

垃圾收集器不是一个可以释放这种资源的地方。请参阅以下两篇关于如何在Java中发布资源的文章 http://c2.com/cgi/wiki?ReleasingResourcesInJava 还有Java终结器的性能问题。他们可能会对如何使用它们提供一些见解和理解。 http://www.enyo.de/fw/notes/java-gc-finalizers.html