代码之家  ›  专栏  ›  技术社区  ›  Newtopian

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

  •  6
  • Newtopian  · 技术社区  · 16 年前

    嗨,我在Java中使用了很多临时文件,我的问题是它们没有被删除。

    如果不需要实现我自己对临时文件管理的处理(我并不难,但我很懒惰,如果我能更好地保存重新发明的控制盘,我还有很多事情要做),是否有一种方法可以确保磁盘上的临时文件以一种相当规律的方式被删除。

    1-使用文件tmp=file.createTempfile(),我当然可以说tmp.deleteonexit(),但是如果该东西在服务中运行,它退出的唯一方式是当它崩溃(很少发生),或者当系统崩溃(例如当驱动器完全充满临时文件并推翻群集时…哎呀!)

    理想情况下,所创建的实例在某个时间点被垃圾收集器收集,并且由于应用程序中有大量空闲时间,如果GC能够完成它的清理,并且在从内存中取消引用实例时,实际上也删除了磁盘上的文件,那么这将是非常明智的。

    我现在看到的唯一方法是重载文件类并添加一个最终确定的方法…如果我这样做的话,也可以使用我自己的临时文件管理器!

    长话短说,我也可以使用垃圾收集器清理系统资源(IE文件)吗?


    谢谢大家的回答。我接受了克里斯托夫的,因为它是最简单的实现方法,也是我最终所做的。

    我想,经过这么多年的清理,我忘记了基本的家政工作,虽然我在C++的好日子里做的很辛苦。

    7 回复  |  直到 16 年前
        1
  •  3
  •   Christoffer    16 年前

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

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

    如果您以任何其他方式执行,例如,如果程序无法断定在执行过程中的任何时候是否应该保留或丢弃临时文件,那么您可能会遇到设计问题。在一些管理器工具中包装文件只会推迟“真正的”解决方案;)

        2
  •  2
  •   Robert Munteanu    16 年前

    你可能想调查一下 PhantomReference :

    幻影引用对象,在收集器确定可以回收其引用后排队。幻像参考最常用于以比Java终结机制可能更灵活的方式调度预验尸清理动作。

        3
  •  2
  •   Bork Blatt    16 年前

    当你的类被破坏时,依靠一个事件来触发不会是万无一失的,并且可能会留下文件。

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

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

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

        4
  •  1
  •   Markus Lausberg    16 年前

    对于这种类型的信息处理,垃圾收集是错误的命名空间。

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

    1. 您应该在不再使用该文件后尝试直接删除该文件。Finalize块可以处理此问题。

    2. 删除您应该使用的退出。

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

        5
  •  1
  •   Mnementh    16 年前

    垃圾收集器对这些东西不起作用。它是为内存管理而设计的,有很多缺点。

    • 您的对象可能在文件不再使用后很长时间内被收集。
    • 你的物品不能保证被收集。

    这两件事经常发生,如果Java是以大堆大小开始的——服务器端的东西并不少见。

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

        6
  •  0
  •   jcoder    16 年前

    您可以为使用 finalizer 当对象被垃圾收集时删除文件。

    但终结器不会以任何可预测的方式被调用,所以我真的根本不建议这样做。

        7
  •  0
  •   Priyank    16 年前

    垃圾收集器不是一个释放这种资源的地方。请看下面这两篇关于如何释放爪哇资源的文章。 http://c2.com/cgi/wiki?ReleasingResourcesInJava 以及Java终结器的性能问题。他们可能会对如何使用它给予一些洞察和理解。 http://www.enyo.de/fw/notes/java-gc-finalizers.html