我的帖子有点太长了,抱歉。这是一个总结:
- 无法删除磁盘上的文件(“JVM 持有文件”错误)。无论是从 Java 代码中删除还是尝试从 Windows 中手动删除文件。
- 该文件的所有流都关闭并设置为空。所有文件对象都设置为空。
- 此时程序什么都不做;但等待 30 分钟后,我可以从 Windows 中删除该文件。诡异的。该文件不再被java使用了吗?另外,由于程序中没有发生任何事情,这表明它不可能是我忘记的某个流(另外,我三次检查没有打开任何东西)。
- 调用 System.gc() 似乎在文件较小时有效。当他们达到大约 20MB 时没有帮助。
[EDIT2] - 我尝试编写一些基本代码来解释,但这很棘手。对不起,我知道这样回答很难。当然,我可以写下如何打开和关闭流:
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("C:\\folder\\myFile.txt")));
for(int i = 0; i < 10; i++)
{
bw.write("line " + i);
bw.newLine();
}
bw.close();
bw = null;
如果我使用了文件对象:
File f = new File("C:\\folder\\myFile.txt");
// use it...
f = null;
基本代码,我知道。但这基本上就是我所做的。 我知道 一个事实 我已经以这种方式关闭了所有流。 我知道一个事实,在我无法删除文件的 30 分钟间隔内程序中没有任何反应,直到我以某种方式神奇地可以。
即使没有连贯的代码,也感谢您的输入。 我很感激。
很抱歉在这里没有提供任何具体的代码,因为我无法查明问题所在(不完全与具体代码相关)。无论如何,事情是这样的:
我编写了一个程序,可以读取、写入和修改磁盘上的文件。由于多种原因,读/写的处理是在不同的线程中完成的,该线程不断运行。
在某些时候,我终止了“读/写”线程,只保留主线程——它等待来自套接字的输入,与文件完全无关,什么都不做。然后,我尝试删除文件(使用 File.delete(),甚至尝试了 nio.Files 删除选项)。
问题是 - 这很奇怪 - 有时有效,有时无效。即使手动转到文件夹并尝试通过 Windows 删除文件,也会给我“文件由 JVM 打开”消息。
现在,我很清楚保留各种流对文件的引用会阻止我删除它。现在已经过去了:) 我已确保所有流都已关闭。我什至将它们的值设置为 null,包括我使用过的任何"file"对象(尽管它应该没有任何区别)。全部设置为null,全部关闭。生成所有这些线程的线程——“读/写”线程——好吧,它终止了,因为它的 run() 方法结束了。
通常,如果我等待大约 30 分钟,JVM 仍在运行,我可以从 Windows 手动删除该文件。错误神奇地消失了。当 JVM 关闭时,我总是可以立即删除文件。
我迷路了。在尝试删除文件之前尝试专门调用 System.gc() ,甚至调用它 10 次(这并不重要)。有时它会有所帮助,但在其他情况下,例如,当文件变大(比如 20MB)时,这并没有帮助。
我在这里错过了什么? 显然,这不可能是我隐含的错误(没有关闭一些流),因为读/写线程已经死了,主线程等待一些不相关的东西(所以程序处于“停顿”状态),我已经明确关闭了所有流,甚至使引用无效 (inStream = null),调用垃圾收集器。
我错过了什么?为什么文件在 30 分钟后“可删除”(当时什么也没有发生——我的代码中没有)。我是否缺少一些温和的引用/垃圾收集之类的东西?
最佳答案
您正在做的事情只会带来问题。你说“如果发生 IOexception,它会立即打印出来”,这可能是真的,但鉴于发生了一些无法解释的事情,我们最好怀疑它。
我会首先确保一切都始终关闭,然后我会关心相关的逻辑(日志记录、退出...)。
反正你做的不是资源应该怎么管理。 answer above是not exactly correct either .无论如何,try-with-resources(@lombok.Cleanup 除外)是唯一的方法,清楚地表明没有任何东西是开放的。其他任何事情都更复杂,更容易出错。我强烈建议在任何地方都使用它。这可能需要做一些工作,但它也会迫使您重新检查所有关键代码段。
诸如使引用无效和调用 GC 之类的事情应该没有帮助......如果他们看起来有帮助,那可能是一个机会。
一些想法:
- 您是否使用内存映射文件?
- 您确定
System.exit
没有被安全管理员禁用吗? - 您是否正在运行防病毒软件?他们喜欢在文件写完后立即扫描文件。
顺便说一句,锁定文件是我从未开始玩 WOW 的原因之一。有时,在罪魁祸首消失后,锁定仍然存在很长时间,至少根据我可以使用的工具。
关于java - 无法删除文件,因为 JVM 持有它 - 一个棘手的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37246541/