Java在FileWriter和BufferedWriter之间的区别


72

两者之间有什么区别?我只是在学习Java ATM,但似乎我可以用两种方式写入文件,即(我没有在这里复制try-catch块。)

FileWriter file = new FileWriter("foo.txt");
file.write("foobar");
file.close();

FileWriter file = new FileWriter("foo.txt");
BufferedWriter bf = new BufferedWriter(file);
bf.write("foobar");
bf.close();

我了解先缓冲数据的概念,这是否意味着第一个示例一个接一个地写入字符,第二个第一个示例将其缓冲到内存中并写入一次?

Answers:


85

如果您使用BufferedWriter则效率更高

  • 在刷新/关闭之间有多次写入
  • 与缓冲区大小相比,写操作较小。

在您的示例中,您只有一次写入,因此BufferedWriter只会增加您不需要的开销。

这是否意味着第一个示例一个接一个地写入字符,第二个第一个将其缓冲到内存中并写入一次

在这两种情况下,字符串都是一次写入的。

如果仅使用FileWriter,则您的write(String)调用

 public void write(String str, int off, int len) 
        // some code
        str.getChars(off, (off + len), cbuf, 0);
        write(cbuf, 0, len);
 }

每次调用write(String)都会进行一次系统调用。


BufferedWriter提高效率的地方是进行多次小写操作。

for(int i = 0; i < 100; i++) {
    writer.write("foorbar");
    writer.write(NEW_LINE);
}
writer.close();

如果没有BufferedWriter,则可能会进行200(2 * 100)次系统调用并将其写入磁盘效率很低。使用BufferedWriter,可以将它们全部一起缓冲,并且由于默认缓冲区大小为8192个字符,因此这仅是1个要写入的系统调用。


我有一个问题,当我使用FileWriter时,在return之后write,java是否保证内容在磁盘中或仅在页面缓存中刷新,而在需要时os将刷新?
Jaskey

@Jaskey,如果您不带缓冲地使用FIleWriter,则write()表示操作系统具有一个副本,该副本最终应写入磁盘。
彼得·劳瑞

8

你是对的。这是外观write()方法BufferedWriter

public void write(int c) throws IOException {
    synchronized (lock) {
        ensureOpen();
        if (nextChar >= nChars)
            flushBuffer();
        cb[nextChar++] = (char) c;
    }
}

如您所见,它确实检查缓冲区是否已满(if (nextChar >= nChars))并刷新缓冲区。然后,它将新字符添加到缓冲区(cb[nextChar++] = (char) c;)。


5

BufferedWriter效率更高。如果内存正确地为我服务,它将节省少量写入,并以较大的一块写入。如果您要进行大量小写操作,则可以使用BufferedWriter。调用写调用到操作系统很慢,因此通常希望写操作尽可能少。


0

根据Java API规范:

FileWriter

编写字符文件的便捷类。此类的构造函数假定默认字符编码和默认字节缓冲区大小是可接受的。

缓冲写入器

将文本写入字符输出流,缓冲字符,以便有效地写入单个字符,数组和字符串。


0

http://docs.oracle.com/javase/1.5.0/docs/api/java/io/BufferedWriter.html

通常,Writer立即将其输出发送到基础字符或字节流。除非需要快速输出,否则建议将BufferedWriter包装在其write()操作可能会很昂贵的所有Writer周围,例如FileWriters和OutputStreamWriters。例如,

PrintWriter out =新的PrintWriter(新的BufferedWriter(新的FileWriter(“ foo.out”))));

将缓冲PrintWriter的输出到文件。如果不进行缓冲,则每次调用print()方法都会导致将字符转换为字节,然后将这些字节立即写入文件中,这可能会非常低效。


-1

在无缓冲的Input / Output(FileWriter,FileReader)中,读或写请求直接由基础OS处理。https://hajsoftutorial.com/java/wp-content/uploads/2018/04/Unbuffered.gif

由于每个这样的请求通常会触发磁盘访问,网络活动或其他相对昂贵的操作,因此这会使程序的效率大大降低。为了减少这种开销,Java平台实现了缓冲的I / O流。BufferedReader和BufferedWriter类提供内部字符缓冲区。写入缓冲写入器的文本存储在内部缓冲区中,并且仅在缓冲区填满或刷新时才写入基础写入器。 https://hajsoftutorial.com/java/wp-content/uploads/2018/04/bufferedoutput.gif

更多https://hajsoftutorial.com/java-bufferedwriter/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.