我已经从我的java编程中创建了一个文件,并使用Apache Commons Logging API记录一些数据,特别是Log4j实现。
完成日志记录后,我将Log类的引用设置为null。当我现在尝试删除我一直记录的文件时,File.delete()返回false。
在调试期间(在调用File.delete()之前从Windows资源管理器中删除文件),我收到通知“无法删除:被其他程序使用”。
我的代码中没有对文件的开放依赖关系(所有流都已关闭)。可以访问该文件的唯一对象是Log对象,我在调用File.delete()之前将其设置为null
无论如何,我可以看到哪个特定对象持有对文件资源的引用? 有没有其他方法可以强制Log对象释放资源,而不是将其设置为null? 我可以强制删除文件吗?
答案 0 :(得分:5)
仅将变量设置为null不会强制对象进行垃圾回收。此外,它有可能在某种静态地图中注册 - 您必须检查实施以确定。 (我认为某些版本使用弱引用,但其他版本不使用。)
你有 删除文件的原因吗?您可能想尝试File.deleteOnExit()
,可能更有可能删除该文件 - 尽管它取决于时间的确切含义。 (另外,如果您反复拨打deleteOnExit
,请注意possible memory leak。)
您可以在应用程序完成后删除文件,还是在下次启动时删除?
或者,您是否可以使用将文件翻转过来的日志实现 - 尝试强制翻转,然后删除旧文件?
答案 1 :(得分:3)
在您的情况下,记录器正在将其写入文件中 - 该文件被另一个进程锁定。
<强>更新强>
问题是log4js的appender对你的文件有写锁定。因此,当appender未关闭时,您无法删除该文件。解决方案是生成较小的文件,或将append标志设置为false,因此当您重新启动服务器时,旧的日志文件会自动删除。
尝试使用
org.apache.log4j.LogManager.shutdown();
关闭以确保终止使用日志文件的所有进程,这样就解决了问题。
确保调用我们自己的Appender实现的close()
方法(它是AppenderSkeleton的子类),以便从getAllAppenders()中正确关闭appender。