Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OutputStream与BufferedOutputStream_Java_File_Java 8_Outputstream_Java 11 - Fatal编程技术网

Java OutputStream与BufferedOutputStream

Java OutputStream与BufferedOutputStream,java,file,java-8,outputstream,java-11,Java,File,Java 8,Outputstream,Java 11,在java 8中,以下各项之间是否存在真正的区别: try (OutputStream os = Files.newOutputStream(path)) { [...] } 及 我读了这篇文章,但它让我很困惑 PS:Java 11中发生了一些变化?不同之处在于,每当您给基础系统一个字节进行写入时,无缓冲的输出流都会对其进行写入调用,而缓冲的输出流则会将要写入的数据存储在缓冲区中,使系统调用仅在调用flush命令后才写入数据。这是为了通过减少I/O操作来提高性能 如中所述,缓冲流应该

在java 8中,以下各项之间是否存在真正的区别:

try (OutputStream os = Files.newOutputStream(path)) {
    [...]
}

我读了这篇文章,但它让我很困惑


PS:Java 11中发生了一些变化?

不同之处在于,每当您给基础系统一个字节进行写入时,无缓冲的输出流都会对其进行写入调用,而缓冲的输出流则会将要写入的数据存储在缓冲区中,使系统调用仅在调用flush命令后才写入数据。这是为了通过减少I/O操作来提高性能

如中所述,缓冲流应该可以减少系统调用的数量。只有当应用程序发出大量小的读或写请求,导致大量系统调用时,这才是相关的。这就是“低效”的意思

通过使用一个大得多的缓冲区(可以通过单个调用读取或写入),并通过从缓冲区复制或复制到缓冲区来满足应用程序请求,您减少了系统调用的数量。如果保存的系统调用比引入的复制开销更昂贵,这将提高性能

因此,使用缓冲流并不总是更好的原因是,并非每个应用程序都会发出如此小的请求。当一个应用程序发出大小合理的请求时,缓冲流所能做的最好的事情就是停止,因此如果它有一个空的缓冲区,并且应用程序发出与缓冲区大小相同甚至更大的请求,缓冲流将把请求直接传递给源流

但是,如果应用程序的缓冲区稍微少一点,则缓冲流将完成其缓冲工作,从而引入额外的复制开销。但是,正如前面所说的,如果您实际保存了系统调用,并且根据体系结构,您可能不得不说,“…如果您实际保存了大量的系统调用”,那么您只会获得一个优势。更大的缓冲区本身并不是一种改进

一个简单的例子是,比方说,您只想将1000字节写入一个文件,如

byte[] data = /* something producing an array of 1,000 bytes */
try (OutputStream os = Files.newOutputStream(path)) {
    os.write(data);
}
因此,如果将输出流包装在一个
BufferedOutputStream
中,您将得到一个默认大小为8192字节的缓冲区。由于这个缓冲流不知道您要总共写入多少,因此它会将请求数据复制到它的缓冲区中,因为它较小,以便在关闭操作期间刷新(写入)。因此,最终,您不会保存任何系统调用,而是会得到复制开销

因此,缓冲流并不总是更有效;在某些情况下,缓冲甚至可能降低性能。此外,有时应用程序对最高性能并不感兴趣,而是对及时写入底层媒体感兴趣。如果流已经是
缓冲输出流
,则在需要时包装
输出流
,以获得缓冲,比选择退出缓冲更容易


当您查看JDK1.4中引入的时,您会注意到没有缓冲通道。相反,它不提供读取或写入单个字节的方法,而且,它迫使程序员使用
ByteBuffer
,来引导他们分离数据的I/O和处理。这是首选方法。

听起来使用
缓冲输出流总是更好。为什么没有一个更简单的方法来创造它呢?此外,我不明白在我链接到DMH的答案中高效阅读和低效阅读之间的区别
java.nio
看起来非常复杂。用它代替经典的
java.io
,真的有什么好处吗?一些基准测试,什么?NIO并不复杂。它有更多的特性,很多东西,旧的
java.io
没有,所以根本没有比较。对于类似的东西,NIO通常比旧的API更容易。对于涉及大数据的某些任务,可能会有显著的性能优势。但是不管性能如何,一旦您需要
java.io
中缺少的特性,您就会发现一致地使用NIO比在API之间来回跳跃更容易。
byte[] data = /* something producing an array of 1,000 bytes */
try (OutputStream os = Files.newOutputStream(path)) {
    os.write(data);
}