3

我已经从我的 java 编程中创建了一个文件,并且正在使用 Apache Commons Logging API 记录一些数据,特别是 Log4j 实现。

日志记录完成后,我将对 Log 类的引用设置为 null。当我现在尝试删除我一直在记录的文件时,File.delete() 返回 false。

在调试期间(在调用 File.delete() 之前)从 Windows 资源管理器中删除文件,我收到通知“无法删除:正在被另一个程序使用”。

我的代码中的文件没有打开的依赖项(所有流都已关闭)。唯一可以访问该文件的对象是 Log 对象,我在调用 File.delete() 之前将其设置为 null

无论如何我可以看到哪个特定对象持有对文件资源的引用?除了将其设置为 null 之外,还有其他方法可以强制 Log 对象释放资源吗?我可以强制删除文件吗?

4

2 回答 2

5

仅将变量设置为 null 不会强制对对象进行垃圾收集。此外,它有可能在某种静态地图中注册 - 您必须检查实现以确定。(我认为有些版本使用弱引用,但其他版本没有。)

您有什么理由必须立即删除该文件吗?您可能想尝试一下File.deleteOnExit(),这可能更有可能删除文件 - 尽管这取决于具体的时间安排。(另外,如果您重复调用,请注意可能的内存泄漏。)deleteOnExit

您可以在应用程序完成后删除文件,或者可能在下次启动时删除文件吗?

或者,您可以使用滚动文件的日志实现 - 尝试强制滚动,然后删除旧文件?

于 2011-03-23T06:58:07.437 回答
3

在您的情况下,记录器正在将其写入文件 - 该文件被另一个进程锁定。


更新:

问题是 log4js 的 appender 在你的文件上有一个写锁。因此,虽然 appender 未关闭,但您无法删除该文件。一个解决方案是您生成较小的文件,或者将附加标志设置为 false,因此当您重新启动服务器时,旧的日志文件会自动删除。

尝试使用

org.apache.log4j.LogManager.shutdown();

关闭确保所有正在使用日志文件的进程都已终止,这样就解决了问题。

确保调用close()我们自己的 Appender 实现(它是 AppenderSkeleton 的子类)的方法,以便它正确地从 getAllAppenders() 关闭附加程序。

于 2011-03-23T06:57:10.280 回答