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



今天,当我正在编写某种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. 流的关闭操作在多大程度上是可观的?

调用close()将刷新所有数据。您在没有启用自动刷新(其中一个构造函数的第二个参数)的情况下构造了PrintWriter,这意味着您必须手动调用flush(),而close()为您完成了该操作。

关闭还释放了打开文件所使用的任何系统资源。虽然虚拟机和操作系统最终会关闭该文件,但最好在完成后关闭它,以节省计算机内存。

您也可以将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在你不需要流的时候自动关闭它们。

当您close a 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():
}

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

流在关闭前自动刷新它们的数据。因此,您可以使用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();
  }
}

PrintWriter对要写入的数据进行缓冲,直到缓冲区满了才写入磁盘。调用close()将确保所有剩余的数据都被刷新,并关闭OutputStream

close()语句一般出现在finally块中。

当我没有包含该语句时,为什么数据没有被写入文件?

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

相关内容

  • 没有找到相关文章

最新更新