FileInputStream是不缓冲的,为什么BufferedInputStream更快?

Rui*_*zhi 2 java io

关于IO,我有两个问题.

答:在教程和一些StackOverflow答案中,他们声称FileInputStream没有缓冲.真的吗 ?

以下代码用于FileInputStream将数据读入字节数组(1024字节)

class Test {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("./fos.txt");
        FileOutputStream fos = new FileOutputStream("./copy.txt");

        byte[] buffer = new byte[1024];   // Is this a buffer ? 

        int len;
        while ((len = fis.read(buffer))!= -1) {
            fos.write(buffer);
        }

        fos.close();
        fis.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

从API,有一行:

public int read(byte b [])抛出IOException

  • @param b:读取数据的缓冲区.

B.如果它们都是缓冲的,它们都将数据放入缓冲区,并从缓冲区中获取数据,那里的确BufferedInputStreamFileInputStream哪个地方更快?

谢谢

Pet*_*rey 5

在教程和一些StackOverflow答案中,他们声称FileInputStream没有缓冲.真的吗 ?

写入任何文件都由OS缓冲,但在这种情况下,它不会被Java缓冲.当您执行许多小写操作时,缓冲有助于1 KB写入不小.

以下代码使用FileInputStream将数据读入字节数组(1024字节)

    int len;
    while ((len = fis.read(buffer))!= -1) {
        fos.write(buffer);
    }
Run Code Online (Sandbox Code Playgroud)

这个循环被打破,因为它假设你总是读取1024个字节,文件长度总是1024的倍数.

相反,你应该写出读取的长度.

    for (int len; (len = fis.read(buffer))!= -1; )
        fos.write(buffer, 0, len);
Run Code Online (Sandbox Code Playgroud)

如果它们都是缓冲的,它们都将数据放入缓冲区,并从缓冲区中获取数据,这恰好是使BufferedInputStream比FileInputStream更快的地方?

在这种情况下,BufferedInputStream默认使用8 KB缓冲区.这样可以将系统调用的数量减少8倍,但是,在您的情况下使用8 KB byte[]并保存一些冗余副本会更简单.

public static void main(String[] args) throws IOException {
    try (FileInputStream fis = new FileInputStream("./fos.txt");
         FileOutputStream fos = new FileOutputStream("./copy.txt")) {

        byte[] buffer = new byte[8 << 10]; // 8 KB
        for (int len; (len = fis.read(buffer)) != -1; )
            fos.write(buffer, 0, len);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.它有助于.能得到你的回答是我的荣幸. (3认同)