如何诊断File.delete()返回false/find unclosed streams?

Mic*_*rdt 13 java io

我正在使用第三方JPEG/EXIF操作库(Mediautil),这让我感到头痛.我想更改图像的EXIF数据.为此,我需要将更新的版本写入临时文件,删除原始文件,然后将临时文件重命名为原始名称.

我的问题是File.delete()调用失败并返回false,可能是因为库仍以某种方式打开它 - 但我已经完成了我在API中找到的所有内容,使其关​​闭所有流.更糟糕的是:问题似乎与时间有关,而且单元测试它发生的地方有时会失败,有时也不会 - 但代码不是多线程的.

奇怪的是,有一个库调用可以解决问题 - 但它也删除了我实际上并不想要的EXIF缩略图.看看代码,我绝对看不到它关闭任何可能保持开放的流.

任何想法如何攻击这个问题?

编辑: 这是在Windows XP,Java 6.另一件事:我发现,如果我在打电话System.gc()之前打电话File.delete(),它可以工作 - 大概是因为这触发了一些终结器.所以它肯定似乎是一个未封闭的流.

ska*_*man 5

我会在这里寻求调试器的帮助.通过这些java.io东西快速挖掘表明,唯一可能的finalize()候选人是FileOutputStream.所以在那里打一个断点,运行你的程序,然后尝试System.gc()触发FileOutputStream.finalize()释放你的流.那应该会给你一个答案,看看这是不是你的问题.

一旦你可以重现它,那么你需要开始匹配实例的FileOutputStream实例化和它们的最终化.一个好的调试器将为每个对象提供内部JVM对象标识符,因此如果您可以在创建OID时跟踪它们,并在它们最终确定时跟踪它们,那么希望您能够将密钥调用finalize与特定关联相关联.叫新的new FileOutputStream.

不过,这可能是一个漫长的过程,取决于您的应用程序的复杂程度.