3

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

6 回答 6

4

调用close()会导致所有数据被刷新。您已经构建了 aPrintWriter而没有启用自动刷新(其中一个构造函数的第二个参数),这意味着您必须手动调用flush(),这close()对您有用。

关闭还可以释放打开文件所使用的任何系统资源。尽管 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 在您不需要时自动关闭流。

于 2013-01-06T15:06:34.750 回答
3

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

您可以使用 实现相同的效果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():
}
于 2013-01-06T15:06:03.490 回答
2

Streams automatically flush their data before closing. So you can either manually flush the data every once in a while using out.flush(); or you can just close the stream once you are done with it. When the program ends, streams close and your data gets flushed, this is why most of the time people do not close their streams!

Using Java 7 you can do something like this below which will auto close your streams in the order you open them.

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();
  }
}
于 2013-01-06T15:12:51.140 回答
2

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

于 2013-01-06T15:05:52.567 回答
1

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

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

于 2013-01-06T15:07:19.757 回答
0

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

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

于 2013-01-06T15:20:35.490 回答