BufferedWriter 的 write(String S) 方法实际上是缓冲的吗?
Does BufferedWriter's write(String S) method actually buffer?
根据Java SE 8 Documentation,BufferedWriter class有以下自己的方法(w.r.t写入数据):
write(char[] cbuf, int off, int len)
write(int c)
write(String s, int off, int len)
正如我通过检查此 class 的源代码确认的那样,它不会覆盖 Writer 的 write(String s)
方法。它只是继承了它。
我的问题是,给定以下代码:
public static void SaveTextToFile(String fileName, String data, boolean append) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)));
bw.write(data);
bw.close();
}
在写入文件之前,数据会被实际缓冲吗?如果不是,缓冲发生在哪些场景?
write(String str)
in Writer
calls write(String str, int off, int len)
, which is overridden in BufferedWriter
。所以你的数据将被缓冲。
关于 BufferedWriter
覆盖哪个方法的推理毫无意义。 non-abstract Writer
class 的所有方法都是根据其他方法实现的,最终以抽象方法之一结束,作为Writer
本身并没有实现任何实际的编写逻辑(怎么可能?)。
由于 Writer
没有任何委托目标的概念,因此不可能有任何方法委托给目标编写器而不被 BufferedWriter
subclass 拦截,因为仅subclass 知道目标。所以所有 write
方法,以及 append
方法,都在 BufferedWriter
的控制之下,如果要写入的数据小于缓冲区的容量,它们将进行缓冲。
也就是说,在您的示例中,
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)));
bw.write(data);
bw.close();
缓冲没有任何优势,因为缓冲区将在随后的 close()
操作中被刷新。所以在最好的情况下,data
比缓冲区大,你只是不必要地创建了一个 BufferedWriter
实例。但是,如果 data
小于缓冲区,则在实际写入数据之前,您还执行了从 data
到缓冲区的不必要的复制操作。
单项写,缓冲没有意义。除此之外,提供一个实际上被忽略的 append
参数是非常危险的,假装一个不存在的功能,特别是当这可能导致目标文件中的现有数据被意外覆盖时。此外,您应该使用 try-with-resources 构造来安全关闭编写器:
public static void SaveTextToFile(String fileName, String data, boolean append)
throws IOException {
try(Writer w = new FileWriter(fileName, append)) {
w.write(data);
}
}
或
// use StandardOpenOption.APPEND to append
public static void SaveTextToFile(String fileName, String data, OpenOption... o)
throws IOException {
Files.write(Paths.get(fileName),
Collections.singleton(data), Charset.defaultCharset(), o);
}
这可能会使您的方法过时,因为它只委托给一个已经存在的方法
根据Java SE 8 Documentation,BufferedWriter class有以下自己的方法(w.r.t写入数据):
write(char[] cbuf, int off, int len)
write(int c)
write(String s, int off, int len)
正如我通过检查此 class 的源代码确认的那样,它不会覆盖 Writer 的 write(String s)
方法。它只是继承了它。
我的问题是,给定以下代码:
public static void SaveTextToFile(String fileName, String data, boolean append) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)));
bw.write(data);
bw.close();
}
在写入文件之前,数据会被实际缓冲吗?如果不是,缓冲发生在哪些场景?
write(String str)
in Writer
calls write(String str, int off, int len)
, which is overridden in BufferedWriter
。所以你的数据将被缓冲。
关于 BufferedWriter
覆盖哪个方法的推理毫无意义。 non-abstract Writer
class 的所有方法都是根据其他方法实现的,最终以抽象方法之一结束,作为Writer
本身并没有实现任何实际的编写逻辑(怎么可能?)。
由于 Writer
没有任何委托目标的概念,因此不可能有任何方法委托给目标编写器而不被 BufferedWriter
subclass 拦截,因为仅subclass 知道目标。所以所有 write
方法,以及 append
方法,都在 BufferedWriter
的控制之下,如果要写入的数据小于缓冲区的容量,它们将进行缓冲。
也就是说,在您的示例中,
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)));
bw.write(data);
bw.close();
缓冲没有任何优势,因为缓冲区将在随后的 close()
操作中被刷新。所以在最好的情况下,data
比缓冲区大,你只是不必要地创建了一个 BufferedWriter
实例。但是,如果 data
小于缓冲区,则在实际写入数据之前,您还执行了从 data
到缓冲区的不必要的复制操作。
单项写,缓冲没有意义。除此之外,提供一个实际上被忽略的 append
参数是非常危险的,假装一个不存在的功能,特别是当这可能导致目标文件中的现有数据被意外覆盖时。此外,您应该使用 try-with-resources 构造来安全关闭编写器:
public static void SaveTextToFile(String fileName, String data, boolean append)
throws IOException {
try(Writer w = new FileWriter(fileName, append)) {
w.write(data);
}
}
或
// use StandardOpenOption.APPEND to append
public static void SaveTextToFile(String fileName, String data, OpenOption... o)
throws IOException {
Files.write(Paths.get(fileName),
Collections.singleton(data), Charset.defaultCharset(), o);
}
这可能会使您的方法过时,因为它只委托给一个已经存在的方法