FileWriter和BufferedWriter之间的Java差异

FileWriter和BufferedWriter之间的Java差异,java,file-io,java-io,Java,File Io,Java Io,它们之间有什么区别?我只是在学习Java ATM,但似乎我可以用两种方式写入文件,即(我没有在这里复制try-catch块) 及 我理解首先缓冲数据的概念,那么这是否意味着第一个示例将字符逐个写入,第二个示例将其缓冲到内存中并写入一次?BufferedWriter更有效。如果我的记忆正确,它可以保存小的写操作,并将写操作保存在一个更大的块中。如果您正在进行大量的小写入,那么我将使用BufferedWriter。对操作系统调用写调用时速度较慢,因此尽可能少的写操作通常是可取的。你说得对。以下是Bu

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


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

BufferedWriter更有效。如果我的记忆正确,它可以保存小的写操作,并将写操作保存在一个更大的块中。如果您正在进行大量的小写入,那么我将使用BufferedWriter。对操作系统调用写调用时速度较慢,因此尽可能少的写操作通常是可取的。

你说得对。以下是
BufferedWriter
方法的
write()
外观:

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;
)。

来自Java API规范:

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

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

通常,写入程序将其输出立即发送到底层字符或字节流。除非需要提示输出,否则建议将BufferedWriter包装在任何write()操作可能代价高昂的编写器周围,例如FileWriter和OutputStreamWriter。比如说,

打印输出 =新的PrintWriter(新的BufferedWriter(新的FileWriter(“foo.out”)))

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


如果您

  • 在刷新/关闭之间进行多次写入
  • 与缓冲区大小相比,写操作很小
在您的示例中,您只有一次写入,因此BufferedWriter只会增加您不需要的开销

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

在这两种情况下,都会立即写入字符串

如果您只使用FileWriter,那么您的写入(字符串)调用

这会对每个要写入的调用(字符串)进行一次系统调用


BufferedWriter提高效率的地方在于多个小型写入

for(int i = 0; i < 100; i++) {
    writer.write("foorbar");
    writer.write(NEW_LINE);
}
writer.close();
for(int i=0;i<100;i++){
作家。写作(“foorbar”);
writer.write(新行);
}
writer.close();
如果没有BufferedWriter,可能会进行200(2*100)次系统调用并写入磁盘,这是效率低下的。使用BufferedWriter,这些都可以一起缓冲,由于默认缓冲区大小为8192个字符,因此这将成为一个系统调用来写入。

在无缓冲输入/输出(FileWriter,FileReader)中,读或写请求由底层操作系统直接处理

这会降低程序的效率,因为每个这样的请求通常会触发磁盘访问、网络活动或其他相对昂贵的操作。为了减少这种开销,Java平台实现了缓冲I/O流。BufferedReader和BufferedWriter类提供内部字符缓冲区。写入缓冲写入器的文本存储在内部缓冲区中,仅在缓冲区填满或刷新时才写入底层写入器。


更多

我有一个问题,当我使用FileWriter时,在
write
返回后,java是否保证内容在磁盘中刷新,或仅在pagecache中刷新,哪个操作系统将在需要时刷新?@Jaskey如果使用FileWriter unbuffered,write()意味着操作系统有一个副本,最终应该写入磁盘。
public void write(int c) throws IOException {
    synchronized (lock) {
        ensureOpen();
        if (nextChar >= nChars)
            flushBuffer();
        cb[nextChar++] = (char) c;
    }
}
 public void write(String str, int off, int len) 
        // some code
        str.getChars(off, (off + len), cbuf, 0);
        write(cbuf, 0, len);
 }
for(int i = 0; i < 100; i++) {
    writer.write("foorbar");
    writer.write(NEW_LINE);
}
writer.close();