我的Java应用程序(这是相当多的代码)执行了大量的文件操作。在我的应用程序中,我需要将文件从一个位置移动到另一个位置,为此我使用JDK7中的Files.move
方法。
当我尝试这样做时,我收到错误,告诉我该文件正在使用中。我知道一个事实是我的代码的一部分是锁定这个资源。
在调用移动/重命名文件的函数之前,如何强制我的Java应用程序释放所有锁?
如果无法做到这一点,是否有一种简单的方法可以检查我的代码的哪一部分正在锁定文件?考虑到代码的数量,在整个代码库中跋涉以找到未封闭的文件句柄将是一场噩梦。
由于
答案 0 :(得分:4)
File()对象不会锁定文件,但FileStream(FileInputStream / FileOutputStream)会锁定它。因此,您必须为Streams编写一个HelperClass(例如Singleton),并记录所有Streams。
但请注意,如果您的代码有泄漏,修复错误要比关闭所有文件要好得多。
答案 1 :(得分:3)
在调试器的帮助下,您可以看到内存中对象的所有实例(在Netbeans中,这将是Windows | Debugging | Loaded Classes,然后右键单击 - > Show instances)。然后,您可以查看所有FileInputStream
/ FileOutputStream
个实例,并找出指向您要移动的文件的实例。找到对文件的引用后,您可以看到谁仍然持有该引用。
如果没有人持有对该文件的引用,则可能在不调用close()
的情况下丢弃该实例,并且该文件通常仅在垃圾回收后才被释放。这使得以前的方法无用,因为我认为调试器会自动为您垃圾收集这些流。也许你可以在流构造函数中放置一个条件断点,并告诉它只在构造函数参数引用你的文件时停止。
如果您找不到任何内容,作为最后的手段,您可以尝试在移动操作之前拨打几个System.gc()
电话,看看您是否有任何改进。显然,这只是快速而肮脏的修复,给你一些时间,直到找到实际问题。
答案 2 :(得分:3)
除了正确关闭流之外的任何解决方案(最好在try.. finally
区块内)将是一项拙劣的工作,并且会使事情变得比现有的更不稳定。
我知道在大型代码库中解决这个问题很痛苦。如果您不想跋涉代码,FindBugs擅长查找未关闭的流。有一个Eclipse插件,您可以将它找到的错误过滤到您感兴趣的那些。