我的帖子有点太长了,抱歉。以下是摘要:
[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,包括我使用的任何“文件”对象(即使它不应该有任何区别)。全部设置为null,全部关闭。生成所有这些线程的线程 - “读/写”线程 - 好吧,它终止了,因为它得到了run()方法的结束。
通常,如果我等待大约30分钟,,而JVM仍在运行,我可以从Windows手动删除该文件。错误神奇地消失了。当JVM关闭时,我可以始终立即删除文件。
我迷失在这里。在尝试删除文件之前尝试专门调用System.gc(),甚至称它为10次(不是它应该重要)。有时它有所帮助,但在其他情况下,例如,当文件变大(比如20MB)时,这没有帮助。
我在这里缺少什么? 显然,这可能不是我的隐含错误(不关闭某些流),因为读/写线程已经死了,主线程等待不相关的东西(所以程序处于“停顿”状态),我已经明确关闭了所有流,甚至使引用无效(inStream = null),调用垃圾收集器。
我错过了什么? 30分钟后为什么文件“可删除”(当时没有任何反应 - 我的代码中没有任何内容)。我错过了一些温和的参考/垃圾收集吗?
答案 0 :(得分:2)
你正在做的只是要求解决问题。你说&#34;如果发生了IOexception,它会立即打印出来#34;这可能是真的,但考虑到莫名其妙的事情,让我们更好地怀疑它。
我首先确保所有内容始终关闭,然后我关心相关逻辑(记录,退出,......)。
无论如何,你所做的并不是如何管理资源。 answer above为not exactly correct either。无论如何,尝试资源是(除了@ lombok.Cleanup)关于唯一的方式,清楚地表明没有任何东西永远敞开。其他任何事情都更复杂,更容易出错。我强烈建议到处使用它。这可能是一些工作,但它也会迫使您重新检查所有关键代码。
无效引用和调用GC这样的事情应该无济于事......如果他们似乎这样做,那可能是一个机会。
一些想法:
System.exit
吗?顺便说一句,锁定文件是WOW从未为我开始的原因之一。在罪魁祸首消失之后,有时锁定会持续很长时间,至少根据我可以使用的工具。
答案 1 :(得分:0)
您是否在try...finally
或try(A a = new A())
区块中关闭了您的信息流?如果不是,则可能不会关闭流。
我强烈建议对所有外部资源使用自动资源块管理(try(A a = new A())
)或try...finally
块。
try(BufferedWriter br = new BufferedWriter(new FileWriter(new File("C:\\folder\\myFile.txt")));
for(int i = 0; i < 10; i++)
{
br.write("line " + i);
br.newLine();
})