[英]How does BufferedWriter work in java
我经常将文本输出到文件。 我想知道: BufferedWriter
如何工作?
当我调用writer.write(text)
时,它是否在文件中写入文本? 如果它不写文本,我是否需要使用flush函数来写入数据?
例如:
File file = new File("statistics.txt");
if (!file.exists()) {
file.createNewFile();
}
else
{
file.delete();
file.createNewFile();
}
FileWriter fileWritter = new FileWriter(file.getAbsoluteFile(),true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
Iterator<Map.Entry<String,Token>> it = listofTakenPairMap.entrySet().iterator();
int isim_isim=0;
int isim_fiil=0;
int zarf_fiil=0;
while (it.hasNext()) {
@SuppressWarnings("rawtypes")
Map.Entry pairs = (Map.Entry)it.next();
Token token=(Token)pairs.getValue();
String str=pairs.getKey()+ " = " +token.getCount();
if(token.getTypeOfPairofToken()==0){//isim-isim
isim_isim+=token.getCount();
}
else if(token.getTypeOfPairofToken()==1){
isim_fiil+=token.getCount();
}
else{ //zarf-fiil
zarf_fiil+=token.getCount();
}
System.out.println(str);
bufferWritter.write(str);
bufferWritter.newLine();
//it.remove(); // avoids a ConcurrentModificationException
}
bufferWritter.newLine();
bufferWritter.write("##############################");
bufferWritter.newLine();
bufferWritter.write("$isim_isim sayisi :"+isim_isim+"$");
bufferWritter.newLine();
bufferWritter.write("$isim_fiil sayisi :"+isim_fiil+"$");
bufferWritter.newLine();
bufferWritter.write("$zarf_fiil sayisi :"+zarf_fiil+"$");
bufferWritter.newLine();
bufferWritter.write("##############################");
bufferWritter.flush();
bufferWritter.close();
如果while循环中发生错误,则文件将在不写入数据的情况下关闭。 如果我在while循环中使用flush
函数,那么为什么我应该使用BufferedWriter
? 如果我错了,请纠正我。
根据定义,缓冲写入器缓冲数据并仅在内存足够时写入它们,以避免过多的往返文件系统。
如果你正确地处理异常,并且像往常一样在finally块中关闭你的流,缓冲区将被刷新到磁盘,到目前为止写入缓冲的写入器的所有内容都将被写入磁盘(当然除非异常)正是由写入磁盘的错误引起的。
因此,解决方案不是每次写入都要刷新,因为它会破坏缓冲编写器的目的。 解决方案是在finally块中关闭(或使用Java 7 trye-with-resources语句,它为您执行此操作)。
流中的数据以块的形式写入磁盘。 因此,当您在OutputStream
或Writer
,您不应期望服务器会自动持久存储到磁盘 - 这实际上很少发生。 您的流程只是虚拟机和主机操作系统中的一个小流程。
如果将数据写入磁盘,则必须等待磁盘I / O完成。 您的代码在此期间未执行,但正在等待。 这将增加服务时间。
此外,频繁的磁盘写入(平均flush()
)将给系统带来沉重的负担,因为它不能简单地覆盖块的全部内容,而是必须多次更新同一块。
所以,这就是为什么像Java这样的语言引入了缓冲。
回答你的问题 :当你write()
数据时,它将被缓冲到一定的水平(直到缓冲区已满)。 之后它将被持久化(写入底层Stream
,例如FileOutputStream
)。 当您调用flush()
或close()
,它将清空缓冲区,因此缓冲的所有字节都将写入基础Stream
。 它们还调用该Stream的flush()
或close()
方法。
如果在循环中发生Exception
,则不会关闭流,因此某些数据可能会丢失。 使用try { } catch (IOException ex) {}
环绕并正确关闭流。
我经常将文本输出到文件。 我想知道:
BufferedWriter
如何工作?
自己查看jdk的源代码
当我调用writer.write(text)时,它是否在文件中写入文本? 如果它不写文本,我是否需要使用flush函数来写入数据?
不。每当你调用write(String s)
,你都会调用: write(str, 0, str.length());
这是openJDK源代码的源代码:
218 public void write(String s, int off, int len) throws IOException {
219 synchronized (lock) {
220 ensureOpen();
221
222 int b = off, t = off + len;
223 while (b < t) {
224 int d = min(nChars - nextChar, t - b);
225 s.getChars(b, b + d, cb, nextChar);
226 b += d;
227 nextChar += d;
228 if (nextChar >= nChars)
229 flushBuffer();
230 }
231 }
232 }
233
118 /**
119 * Flushes the output buffer to the underlying character stream, without
120 * flushing the stream itself. This method is non-private only so that it
121 * may be invoked by PrintStream.
122 */
123 void flushBuffer() throws IOException {
124 synchronized (lock) {
125 ensureOpen();
126 if (nextChar == 0)
127 return;
128 out.write(cb, 0, nextChar);
129 nextChar = 0;
130 }
131 }
如你所见,它不会直接写。 只有当if (nextChar >= nChars)
,它才会刷新缓冲区本身(默认为private static int defaultCharBufferSize = 8192;
通过使用它的“换行”类。(在java中, Java IO是使用Decorator Design Pattern设计的 。最后,它将调用write(char[] chars, int i, int i1)
。)
如果while循环中发生错误,则文件将在不写入数据的情况下关闭。 如果我在while循环中使用flush函数,那么为什么我应该使用
BufferedWriter
?
IO成本非常昂贵。 除非您需要“即时”查看输出(例如,使用最新更新随时查看日志),您应该让自动完成以提高性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.