我正在尝试以编程方式从由多个Java和非Java服务器组成的正在运行的(!)系统中清除日志文件。我使用了Java的File.delete()操作,它通常工作正常。我对当前正在使用的日志文件没有被删除也很好,所以我只是在 File.delete() 返回 false 时将其记录为警告。
但是,在当前仍由非 Java 应用程序(Postgres、Apache HTTPD 等)写入的日志文件中,Java 应用程序也可能受到影响,但我还没有注意到,无论如何,它们都使用相同的日志记录框架,这似乎没问题)实际上并没有被删除(这是我所期望的),但是,File.delete() 为它们返回"true"。但是这些文件不仅仍然存在于文件系统上(Windows资源管理器和"dir"仍然显示它们),而且之后它们无法访问...当我尝试使用文本编辑器等打开它们时。我收到"访问被拒绝"或类似的错误消息,当我尝试使用资源管理器复制它们时,它还声称我没有权限,当我使用资源管理器检查其"属性"时,它给了我"您无权查看或编辑此对象的权限"。
需要明确的是:在我运行 File.delete() 操作之前,我可以毫无问题地访问或删除这些文件,删除操作会"破坏"它们。一旦我停止应用程序,文件就会消失,重新启动时,应用程序从头开始创建它,一切恢复正常。问题是,当日志文件清除操作后未重新启动应用程序时,应用程序会记录到 nirvana。
这种行为让我想起了 Linux 的文件删除行为:如果您删除仍由应用程序保持打开状态的文件,它将从文件系统中消失,但应用程序 - 仍然持有文件句柄 - 将愉快地继续写入该文件,但之后您将永远无法访问它。唯一的区别是这里的文件在 FS 中仍然可见,但否则也无法访问。
我应该提到我的Java程序和应用程序本身都在"系统"用户下运行。
我还尝试了 Files.delete(),据称它会抛出一个指示错误的 IOException......但似乎没有错误。
我试图解决此问题的是使用此处描述的方法检查文件当前是否已锁定 https://stackoverflow.com/a/1390669/5837050,但这仅适用于某些文件,而不是所有文件。
我基本上需要一种可靠的方法(至少对于 Windows,如果它也适用于 Linux,那就太好了)来确定某个文件是否仍在被某个程序使用,所以我不能删除它。
任何提示表示赞赏。
重现它,但它似乎是操作系统的预期行为,通常不同的应用程序与对此类文件拥有所有权的不同用户一起运行,但我知道你想要像主清除 Java 检查未使用的日志文件以删除它们(当然,运行足够的授权)。
因此,考虑到操作系统行为不会改变,我建议使用"滚动文件追加器"策略配置日志,然后检查与这些策略匹配的文件。
检查回滚策略以进行回滚以使您了解:http://logback.qos.ch/manual/appenders.html#onRollingPolicies
例如,如果您的追加文件策略是"超过一天或大于 1Gb",则只需删除上次版本日期早于一天或大小为 1GB 的文件。使用此规则,您将确保删除未使用的日志文件。
请注意,使用适当的滚动策略,也许您甚至不需要清除方法,请查看此配置示例:
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
我希望这能对你有所帮助!!