在阅读关于Java的初学者书籍时,我已经读过,一旦不再需要流,必须始终关闭它。为什么会这样?把它打开怎么了?
考虑以下示例:
import java.io.*;
public class SOStreamTest {
public static void main(String[] args){
try{
FileWriter writer = new FileWriter("Foo.txt");
writer.write("hello foo!");
//Writer.close(); <-!Line in Question -->
}catch(IOException ex){
ex.printStackTrace();
}
}
}
正如预期的那样,出现了一条警告信息,“资源泄漏:”作家“永远不会关闭。”
答案 0 :(得分:2)
您知道在Windows PC上尝试删除某个文件但是其他程序正在使用该文件吗?这就是为什么你应该总是关闭文件输入或输出流的一个原因。
另一个例子,对于Linux来说,这次是每个文件输入或输出流都需要一个称为文件句柄的东西。给定的Linux系统只允许存在一定数量的文件句柄,如果达到最大值,就会发生不好的事情。
关闭流时,文件句柄将被释放。
其他输入和输出流可能会导致类似的问题,例如,无法关闭网络流可能会打开与另一台计算机的连接。这样做几千次,你将耗尽端口或杀死你正在连接的机器。
答案 1 :(得分:2)
首先,你期望你的应用程序将在main的底部结束,但是main是一种常规方法,可能会被其他继续运行的代码调用。
您不希望流式传播的原因是它们往往与操作系统资源相关联,后者比内存更受限制。
套接字更加麻烦,因为您可能会保留程序和远程主机的资源。
答案 2 :(得分:1)
关闭你的溪流的重要性可以减少到两个一个主要点 s :
首先,流通常与某些系统资源(套接字,文件,数据库连接)相关联,一般来说,这是一种很好的做法,可以作为昂贵的资产处理,因为它可能是共享的通过其他过程甚至减慢系统速度。
此外,如果你没有关闭一个流,它的内存表示将保持活动状态,因为没有任何提示告诉垃圾收集器这个被反对者可以被删除。
因此,通过关闭一个流你明智地使用 一个系统资源和你的进程&#39;记忆空间。
编辑:正如下面的评论部分所指出的,我所说的关于垃圾收集的内容是错误。然而,可能会发生一个流可能在被GC销毁之前被关闭,因为许多基本流(至少在Java中)包括在close()
方法上调用finalize()
。关于这个主题,请参阅此SO thread。
答案 3 :(得分:0)
最常见的原因之一是确保所有内容都写在输出中。
授予我们的应用程序访问文件中的数据写入可能需要一些时间。因此,为了避免每次写入单字节请求它,我们使用缓冲区,如BufferedWriter
,我们存储大部分数据,当它已满时,它将自动请求写入访问,写入其存储的数据,以及清洁缓冲区。
但是在缓冲区未满且我们没有更多数据需要写入的情况下,我们需要显式通知缓冲区将数据写入文件。我们可以通过调用flush
方法或调用close
隐式调用flush
的方法来实现。没有它,我们的文件将不包含当前存储在缓冲区中的部分。