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

2022-09-04 03:34:58

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

当我尝试执行此操作时,我收到一个错误,告诉我该文件正在使用中。我知道一个事实,是我代码的某些部分锁定了这个资源。

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

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

谢谢


答案 1

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

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

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


答案 2

File() 对象不会锁定文件,但 FileStream(FileInputStream/FileOutputStream)会锁定该文件。因此,您必须为流编写一个帮助器类(例如单例),其中记录所有流。

但请注意,如果您的代码中存在泄漏,则修复错误比硬关闭所有文件要好得多。