我需要找到我的Java应用中的哪个对象打开一个文件。这是用于调试的,因此欢迎使用工具或实用程序。
如果找到哪个对象过于具体,哪个类也会非常有帮助。
答案 0 :(得分:4)
这可能很棘手。您可以首先使用分析器,例如VisualVM(免费)或YourKit(非免费)来检查内存中的java.io.File个对象。如果你能找到一个你感兴趣的路径,那可能会指向你正确的方向。问题是,对于仍然打开文件的应用程序,不一定存在File对象。
您的下一步可能是在FileInputStream和FileOutputStream中设置断点(除非您知道是否正在读取或写入文件),附加调试器,并注意您的文件是其中一个开了。但当然,还有其他打开文件的方法。例如,您可能还需要放弃Class.getResourceAsStream()和URL.openConnection()之类的内容。
您的最后一招可能是尝试使用无所不知的调试器,例如ODB或TOD。我对他们只有有限的经验,但他们声称“知道一切”。你只需要弄清楚如何提出正确的问题。
答案 1 :(得分:0)
使用AspectJ并拦截对各种开放文件流的调用。使用周围的方面。请注意,这只能告诉您哪个对象打开了流,但显然该对象可以传递对流的引用,所以......
答案 2 :(得分:0)
以下是特定于 Windows 和 IntelliJ 的,但对于其他操作系统和 IDE 可能类似。
此外,它依赖于 JDK 内部,以下是为 JDK 11 编写的。
handle
。为此,您可以使用 Windows Sysinternals Handle tool(另请参阅 this Server Fault question):
.\handle64.exe -p java
D7C: File C:\Users\Someone\myfile.txt
(注意:大多数终端都提供搜索功能,对于cmd.exe
是Ctrl + F;对于Windows Terminal是Ctrl + ⇧ + F.)D7C
),记下它。java.io.FileDescriptor
handle == 0xhandle
,handle 是您在第 2 步中记下的值(在本例中为 handle == 0xD7C
)。fd ==
。)FileCleanable
中的引用很可能会被忽略)这不会总是回答哪个调用者忘记关闭文件,但它可能会给出提示。例如,您可以在相关类中设置更多断点以找出谁打开了文件。