繁体   English   中英

BufferedInput/OutputStream 在 Java 中实际做了什么

[英]what does BufferedInput/OutputStream actually do in Java

我正在学习 Java I/O,我对以下两个复制文件的片段之间的区别有疑问:

片段 1,使用 FileInput/OutputStream 和一个字节数组:

public static void main(String[] args) throws IOException {
    //function: copy a jpg file
    //1.get a jpg as source file
    File f1 = new File("d:\\LOL.jpg");

    //2.get a target file
    File f2 = new File("d:\\LOL2.jpg");

    //3.using FileInputStream for source file
    FileInputStream fis = new FileInputStream(f1);

    //4.using FileOutputStream for target file
    FileOutputStream fos = new FileOutputStream(f2);

    //5.copy the file by byte array
    byte[] b = new byte[1024*8];
    int len = fis.read(b);
    while(len!=-1){
        fos.write(b,0,len); 
        len = fis.read(b); 
    }

    //6.close stream
    fos.close();
    fis.close();
}

片段 2,使用 BufferedInput/OutputStream

public static void main(String[] args) throws IOException {
    //1.get a jpg as source file
    File f1 = new File("d:\\LOL.jpg");

    //2.get a target file
    File f2 = new File("d:\\LOL2.jpg");

    //3.using FileInputStream for source file
    FileInputStream fis = new FileInputStream(f1);

    //4.using FileOutputStream for target file
    FileOutputStream fos = new FileOutputStream(f2);

    //5.use BufferedInputStream:
    BufferedInputStream bis = new BufferedInputStream(fis);

    //6.use BufferedOutputStream:
    BufferedOutputStream bos = new BufferedOutputStream(fos);

    //7.copy
    byte[] b = new byte[1024*8];
    int len = bis.read(b);
    while(len!=-1){
        bos.write(b,0,len);
        len = bis.read(b);
    }

    //8.close
    bos.close();
    bis.close();

我查看了 BufferedInput/OutputStream 的源代码,发现它的默认缓冲区大小是 1024*8 字节在此处输入图像描述

我的困惑是:

  1. BufferedInput/OutputStream 中的内部缓冲区实际上做了什么? 它只是扮演与片段 1 中的字节数组相同的角色吗?

  2. 如果他们扮演同样的角色,那为什么 BufferedInput/OutputStream 更有效率呢?

不同之处在于,每次给它一个字节要写入时,无缓冲都会对底层系统进行写入调用,而缓冲的 output stream 会将要写入的数据存储在缓冲区中,使系统调用仅在之后写入数据调用冲洗命令。 这是为了通过减少调用的 I/O 操作来提高性能。

https://docs.oracle.com/javase/8/docs/api/java/io/BufferedOutputStream.html https://docs.oracle.com/javase/8/docs/847OutputStream846/javase/8/docsio/847Output86/javase

它只是扮演与片段 1 中的字节数组相同的角色吗?

是的,一次读/写多个字节

如果他们扮演同样的角色,那为什么 BufferedInput/OutputStream 更有效率呢?

它不是更有效率......只有当你使用相同的缓冲区大小和相同的读/写操作时才会......

使用缓冲区可能效率更低! 如果你强制读取 1M 缓冲区但你只需要第一个字节。

缓冲区大小可以极大地影响同一算法的效率,或者使不同的算法 go 从最低到最高效率。

还有其他考虑因素会极大地影响分布式系统的操作,因为在 output 缓冲区满之前,没有信息到达接收者

当一些用户说没有画任何东西时,一个非常常见的效果......不,不是没有画任何东西,而是缓冲区还没有被填满,需要用一些flush操作来强制转储。

在这方面有趣的阅读可能是: Deadlock-free buffer configuration for stream computing

Stream 计算是并行和分布式计算的流行范例,其中计算节点通过先进先出数据通道连接。 每个通道都可以看作是几个数据缓冲区的串联,包括发送方的 output 缓冲区和接收方的输入缓冲区。 缓冲区大小的配置会影响应用程序的性能和正确性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM