Java的File.delete()有时会留下无法访问的文件(Windows)

时间:2016-07-08 13:25:16

标签: java file delete-file

我正在尝试以编程方式从包含多个Java和非Java服务器的正在运行的(!)系统中清除日志文件。我使用Java的File.delete()操作,它通常工作正常。我对目前正在使用的日志文件没有被删除也完全没问题,所以每当File.delete()返回false时我都会将其记录为警告。

但是,在当前仍由NON-Java应用程序(Postgres,Apache HTTPD等)编写的日志文件中,Java应用程序可能也会受到影响,但我还没有注意到,并且所有人都在使用相同的日志记录无论如何,框架似乎没有被删除(这是我所期望的),但是,File.delete()为它们返回“true”。 但是这些文件不仅仍存在于文件系统上(Windows资源管理器和“dir”仍然显示它们),但之后它们无法访问...当我尝试用文本编辑器打开它们时,我得到“访问被拒绝”或者类似的错误消息,当我尝试用资源管理器复制它们时,它还声称我没有权限,当我用资源管理器检查它的“属性”时,它给了我“你没有权限查看或编辑这个对象的权限”

为了清楚起见:在我运行File.delete()操作之前,我可以毫无问题地访问或删除这些文件,删除操作会“中断”它们。一旦我停止应用程序,文件就会消失,重启后,应用程序会从头开始创建它,一切都恢复正常。 问题是当在日志文件清除操作之后没有重新启动应用程序时,应用程序会记录到必杀技。

这种行为让我想起了Linux的一些文件删除行为:如果删除一个仍由应用程序保持打开的文件,它会从文件系统中消失,但应用程序 - 仍然保持文件句柄 - 将很高兴继续写入该文件,但之后您将永远无法访问它。唯一的区别是这里的文件在FS中仍然可见,但也无法访问。

我应该提到我的Java程序和应用程序本身都在运行“system”用户。

我还尝试过Files.delete(),据称会抛出一个IOException来指示错误......但似乎没有错误。

我尝试解决此问题的方法是使用此处描述的方法https://stackoverflow.com/a/1390669/5837050检查文件当前是否已锁定,但这仅适用于某些文件,而不适用于所有文件。

我基本上需要一种可靠的方法(至少对于Windows,如果它也适用于Linux,那会很棒)来确定某个程序是否还在使用某个文件,所以我不能删除它。

任何提示都表示赞赏。

1 个答案:

答案 0 :(得分:0)

我还没有复制它,但它似乎是一个操作系统预期的行为,通常不同的应用程序与不同的用户运行,这些用户对这种类型的文件拥有所有权,但我知道你想要像主清除Java那样检查日志文件而不是用于删除它们(当然有足够的授权运行)。

因此,考虑到OS行为不会改变,我建议使用“roll file appender”策略配置日志,然后检查符合这些策略的文件。

检查回滚策略以进行回溯以使您了解: http://logback.qos.ch/manual/appenders.html#onRollingPolicies

例如,如果您的appender文件策略是“超过一天或超过1Gb”,则只删除上次编辑日期早于一天或大小为1Gb的文件。使用此规则,您将确保删除未使用的日志文件。

请注意..如果使用正确的滚动策略,您甚至可能不需要清除方法,请查看此配置示例:

  <!-- keep 30 days' worth of history capped at 3GB total size -->
  <maxHistory>30</maxHistory>
  <totalSizeCap>3GB</totalSizeCap>

我希望这可以帮助你一点!!