关于用于关闭流的close方法()

时间:2013-01-06 15:03:31

标签: java stream

今天,当我正在处理某种类型的servlet时,我正在使用以下代码执行写操作

 File f=new File("c:/users/dell/desktop/ja/MyLOgs.txt");
        PrintWriter out=new PrintWriter(new FileWriter(f,true));
        out.println("the name of the  user is "+name+"\n");
        out.println("the email of the user is "+ email+"\n");
        out.close();             //**my question is about this statement**

当我没有使用该语句时,servlet编译得很好,但它没有写任何文件,但是当我包含它时,写操作就成功执行了。我的问题是:

  1. 当我不包含该语句时,为什么没有将数据写入文件(即使我的servlet编译没有任何错误)?
  2. 流程的关闭操作在多大程度上相当可观?

6 个答案:

答案 0 :(得分:4)

调用close()会导致刷新所有数据。您构建了PrintWriter而没有启用自动刷新(其中一个构造函数的第二个参数),这意味着您必须手动调用flush() close()为您执行的操作。

Closing还可以释放文件打开时使用的所有系统资源。尽管VM和操作系统最终将关闭该文件,但最好在完成后关闭它以节省计算机内存。

您也可以将close()置于finally块内,以确保始终被调用。如:

PrintWriter out = null;
try {
    File f = new File("c:/users/dell/desktop/ja/MyLOgs.txt");
    out = new PrintWriter(new FileWriter(f,true));
    out.println("the name of the  user is "+name+"\n");
    out.println("the email of the user is "+ email+"\n");
} finally {
    out.close();
}

请参阅:PrintWriter

Sanchit也提出了一个很好的观点,让Java 7 VM在你不需要它们的时候自动关闭你的流。

答案 1 :(得分:3)

当您close PrintWriter时,它会将所有数据刷新到您想要数据的任何位置。它不会自动执行此操作,因为如果它每次写入某些内容时都会执行此操作,那么写入操作并不是一个简单的过程,效率会非常低。

您可以使用flush();获得相同的效果,但是您应该始终关闭流 - 请参阅此处:http://www.javapractices.com/topic/TopicAction.do?Id=8和此处:http://docs.oracle.com/javase/tutorial/jndi/ldap/close.html。使用完毕后,请始终在流上调用close();。此外,为确保始终关闭,无论例外情况如何,您都可以执行此操作:

try {
    //do stuff
} finally {
    outputStream.close():
}

答案 2 :(得分:2)

这是因为PrintWriter缓冲了你的数据,以便不为每次写操作重复进行I / O操作(这是非常昂贵的)。当您调用close()时,缓冲区会刷新到文件中。您也可以调用flush()强制写入数据而不关闭流。

答案 3 :(得分:2)

Streams会在关闭前自动刷新数据。因此,您可以使用out.flush();每隔一段时间手动刷新数据,也可以在完成后关闭流。当程序结束时,流关闭并且您的数据被刷新,这就是为什么大多数时候人们不关闭他们的流!

使用Java 7,你可以在下面执行以下操作,它会按照你打开它们的顺序自动关闭你的流。

public static void main(String[] args) {
  String name = "";
  String email = "";
  File f = new File("c:/users/dell/desktop/ja/MyLOgs.txt");
  try (FileWriter fw = new FileWriter(f, true); PrintWriter out = new PrintWriter(fw);) {
    out.println("the name of the  user is " + name + "\n");
    out.println("the email of the user is " + email + "\n");
  } catch (IOException e) {
    e.printStackTrace();
  }
}

答案 4 :(得分:1)

PrintWriter缓冲要写入的数据,并且在缓冲区已满之前不会写入磁盘。调用close()将确保刷新任何剩余数据以及关闭OutputStream

close()语句通常出现在finally块中。

答案 5 :(得分:0)

为什么在我不包含该声明时数据没有写入文件?

当进程终止时,将释放非托管资源。对于InputStreams,这很好。对于OutputStreams,您可能会丢失缓冲数据,因此在退出程序之前至少应该刷新流。