繁体   English   中英

如何找出哪个对象在 Java 中打开了文件?

[英]How can I find out which object has a file open in Java?

我需要找出我的 Java 应用程序中的哪个对象打开了文件。 这是用于调试,因此欢迎使用工具或实用程序。

如果找到哪个对象太具体,哪个也会很有帮助。

那可能很棘手。 您可以首先使用分析器,如VisualVM (免费)或YourKit (非免费)来检查内存中的java.io.File对象。 如果你能找到一个你感兴趣的路径,那可能会为你指明正确的方向。 问题在于,对于应用程序仍然打开文件来说,文件对象不一定必须存在。

您的下一步可能是在FileInputStreamFileOutputStream 中设置断点(除非您知道文件是被读取还是写入),附加调试器,并观察您的文件是否被其中之一打开。 当然,还有其他打开文件的方法。 例如,您可能还需要放样Class.getResourceAsStream()URL.openConnection() 之类的东西。

你最后的手段可能是尝试一个无所不知的调试器,比如ODBTOD 我对他们的经验有限,但他们声称“无所不知”。 你只需要弄清楚如何提出正确的问题。

使用 AspectJ 并拦截对各种打开文件流的调用。 使用周围方面。 请注意,这只能告诉您哪个对象打开了流,但显然该对象可以传递对流的引用,所以......

以下是 Windows 和 IntelliJ 特定的,尽管它可能与其他操作系统和 IDE 类似。

此外,它依赖于 JDK 内部结构,以下是为 JDK 11 编写的。


  1. 找出文件的handle 为此,您可以使用 Windows Sysinternals Handle 工具(另请参阅此服务器故障问题):
     .\\handle64.exe -p java
  2. 在输出中搜索相关文件,例如:
     D7C: File C:\\Users\\Someone\\myfile.txt
    (注意:大多数终端提供搜索功能,对于cmd.exeCtrl + F ;对于Windows 终端Ctrl + + F 。)
    冒号前的值很重要(在本例中为D7C ),记下它。
  3. 在 IntelliJ 中,使用调试器暂停执行。
  4. 打开内存选项卡
  5. 搜索java.io.FileDescriptor
  6. 右键单击结果并选择“显示实例”
  7. , with handle being the value you noted down in step 2 (in this example handle == 0xD7C ).作为条件输入handle == 0x handle是您在第 2 步中记下的值(在此示例中handle == 0xD7C )。
    (注意:在 Unix 下,您可能必须比较fd == 。)
    ➔ 您应该看到一个结果
  8. 右键单击结果并选择“显示引用对象...”
  9. 在结果上,您可以继续选择“显示引用对象...”,直到找到相关结果( FileCleanable的引用很可能会被忽略)

这不会总是回答哪个调用者忘记关闭文件,但它可能会给出提示。 例如,您可以在相关类中设置更多断点以找出谁打开了文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM