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

Java 关于用于关闭流的close方法(),java,stream,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.pri

今天,当我在开发某种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编译得很好,但它没有向文件写入任何内容,但当我包含它时,写入操作成功执行。我的问题是:

  • 为什么当我没有包含该语句时数据没有写入文件(即使我的servlet编译时没有任何错误)
  • 在多大程度上,关闭操作对溪流是相当重要的

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

    当您
    关闭
    一个
    PrintWriter
    时,它会将所有数据刷新到您希望数据去的任何地方。它不会自动这样做,因为如果每次你写东西的时候它都会这样做,那将是非常低效的,因为写东西不是一个容易的过程

    您可以使用
    flush()实现相同的效果,但您应该始终关闭流-请参见此处:和此处:。始终调用
    close()操作。此外,为了确保它始终处于关闭状态,无论是否存在异常,您可以执行以下操作:

    try {
        //do stuff
    } finally {
        outputStream.close():
    }
    
    调用
    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();
    }
    
    见:


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

    PrintWriter
    缓冲要写入的数据,因此在缓冲区满之前不会写入磁盘。调用
    close()


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

    流在关闭前自动刷新其数据。因此,您可以使用
    out.flush()每隔一段时间手动刷新一次数据或者,您可以在处理完流后关闭它。当程序结束时,流关闭,数据被刷新,这就是为什么大多数时候人们不关闭流

    使用Java7,您可以执行下面类似的操作,按照打开流的顺序自动关闭流

    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();
      }
    }
    

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


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

    您应该在
    中调用
    close()
    ,最后
    -block那么输入流呢,它们也需要关闭操作吗?是的,您还应该使用相同的
    close()
    方法关闭
    InputStream
    s。当不再需要时,最好关闭任何可关闭的
    。()