强制java释放java中的所有文件锁/句柄

强制java释放java中的所有文件锁/句柄,java,file,file-locking,Java,File,File Locking,我的Java应用程序(相当多的代码)执行很多文件操作。在我的应用程序中,我需要将文件从一个位置移动到另一个位置,为此,我使用JDK7中的Files.move方法 当我尝试这样做时,我得到一个错误,告诉我该文件正在使用中。我知道锁定此资源的是我代码的某个部分 在调用移动/重命名文件的函数之前,如何强制Java应用程序释放所有锁 如果这是不可能的,是否有一种简单的方法来检查我的代码的哪一部分正在锁定文件?考虑到代码的数量,在我的整个代码库中寻找未关闭的文件句柄将是一场噩梦 谢谢在调试器的帮助下,您可

我的Java应用程序(相当多的代码)执行很多文件操作。在我的应用程序中,我需要将文件从一个位置移动到另一个位置,为此,我使用JDK7中的
Files.move
方法

当我尝试这样做时,我得到一个错误,告诉我该文件正在使用中。我知道锁定此资源的是我代码的某个部分

在调用移动/重命名文件的函数之前,如何强制Java应用程序释放所有锁

如果这是不可能的,是否有一种简单的方法来检查我的代码的哪一部分正在锁定文件?考虑到代码的数量,在我的整个代码库中寻找未关闭的文件句柄将是一场噩梦


谢谢

在调试器的帮助下,您可以看到内存中对象的所有实例(在Netbeans中,这将是Windows |调试|加载的类,然后右键单击->显示实例)。然后,您可以查看您拥有的所有
FileInputStream
/
FileOutputStream
实例,并识别那些指向您试图移动的文件的实例。找到文件的引用后,您可以看到谁仍然持有该引用

如果没有人持有对该文件的引用,则该实例可能在未调用
close()
的情况下被丢弃,并且该文件通常仅在垃圾收集之后才会被释放。这使得前面的方法毫无用处,因为我认为调试器会自动为您垃圾收集这些流。也许您可以在流构造函数中放置一个条件断点,并告诉它仅在构造函数参数引用您的文件时停止


如果您找不到任何东西,作为最后手段,您可以尝试在移动操作之前进行几个
System.gc()
调用,看看是否有任何改进。显然,这只是一个快速而肮脏的解决方案,给你一些时间,直到你发现实际的问题。

除了正确关闭流之外的任何解决方案(最好是在
try..finally
块内)都将是一个拙劣的工作,并有可能使事情变得比现在更不稳定

我知道在一个庞大的代码库中修复这个问题是一件痛苦的事情。如果您不想在代码中跋涉,则可以很好地查找未关闭的流。有一个Eclipse插件,您可以将它发现的bug过滤到您感兴趣的人。

File()对象不会锁定文件,但FileStream(FileInputStream/FileOutputStream)会锁定它。因此,您必须为您的流编写一个HelperClass(例如Singleton),记录所有流


但是请注意,如果代码中有漏洞,修复该漏洞比硬关闭所有文件要好得多。

实际上
文件
实例不会锁定文件。
文件
只是文件或目录路径名的表示形式
System.gc()
从不关闭任何打开的文件流。关于
文件
,您是对的。我将答案更正为参考
FileInputStream
/
FileOutputStream
。然而,我保留了我关于
System.gc()
的建议:这两个类有一个
finalize
方法来关闭流,因此,如果您只是在不调用close的情况下丢弃对象,垃圾收集可能会有所帮助。关于文件流中的finalize(),您是对的,它可能会有所帮助。不过它很脆弱!您无法控制垃圾收集的发生时间和收集的内容,因此您不希望在生产中依赖这样的行为。也许有帮助:当类加载器加载一个jar文件时,这个jar文件描述符会永远保持不变吗?还是不同的实施方式有所不同?那么默认的类加载器呢?