今天,当我正在处理某种类型的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编译得很好,但它没有写任何文件,但是当我包含它时,写操作就成功执行了。我的问题是:
答案 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,您可能会丢失缓冲数据,因此在退出程序之前至少应该刷新流。