当前位置: 首页 > 知识库问答 >
问题:

是FileInputStream没有缓冲,为什么BufferedInputStream更快?

周鸿运
2023-03-14

关于IO,我有两个问题。

A.在一个教程和一些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();
    }
}

从API,有一行:

公共整数读取(字节b[])引发IOException

  • @参数b:将数据读入的缓冲区

B.如果它们都是缓冲的,它们都将数据放入缓冲区,并从缓冲区中获取数据,那么使BufferedInputStream比FileInputStream更快的地方到底在哪里?

非常感谢。

共有2个答案

尤俊誉
2023-03-14

的确,FileInputStream没有缓冲,但在读取时,它确实提供了有限的类似缓冲区的功能。

最大的区别是BufferedInputStream支持mark()和reset(),而as FileInputStream不支持。

标记(int readlimit)将允许您在流中设置一个位置以供以后使用。reset()将您在流中的位置设置为mark(int readLimit)中指定的位置

为了支持mark()和reset()BufferedInputStream,必须维护一个内部缓冲区,而as FileInputStream则不能。

柯星辰
2023-03-14

在一个教程和一些StackOverflow的答案中,他们声称FileInputStream没有被修复。是真的吗?

对任何文件的写入都是由操作系统缓冲的,但是,在这种情况下,它不是由Java缓冲的。缓冲有助于在执行许多小写入时,1 KB的写入并不小。

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

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

此循环中断,因为它假设您总是精确读取1024字节,并且文件长度总是1024的倍数。

相反,您应该写入读取的长度。

    for (int len; (len = fis.read(buffer))!= -1; )
        fos.write(buffer, 0, len);

如果它们都被缓冲,那么它们都将数据放入缓冲区,并从缓冲区中获取数据,究竟是什么地方使BufferedInputStream比FileInputStream更快?

在这种情况下,默认情况下BufferedInputStream将使用8 KB的缓冲区。这将使系统调用的数量最多减少8倍,但是,在您的情况下,只使用8 KB的字节[]并保存一些冗余副本会简单得多。

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);
    }
}
 类似资料:
  • 我读到FileWriter和BufferedWriter的区别在于FileWriter直接写入文件(逐字符),white BufferedReader使用缓冲区。如果是,为什么FileWriter有缓冲区?例如,如果我创建一个FileWriter对象,如下所示: 而且,如果我在程序结束时不刷新或关闭写入器,它将不会向文件写入任何内容。这意味着它也使用缓冲区。拜托,解释一下?

  • Java中FileInputStream和BufferedInputStream的区别是什么?

  • 问题内容: 我试图使用FileInputStream将文件读入数组,而一个〜800KB的文件花了大约3秒钟才能读入内存。然后,我尝试了相同的代码,只是将FileInputStream包装到BufferedInputStream中,这花费了大约76毫秒。为什么即使我仍在逐字节读取文件,使用BufferedInputStream逐字节读取文件的速度还是这么快?这是代码(其余代码完全无关)。请注意,这是

  • 问题内容: 什么是输出缓冲?为什么在PHP中使用它? 问题答案: Web开发人员的输出缓冲,初学者指南 如果没有输出缓冲(默认),则HTML将通过脚本逐步地作为PHP进程发送到浏览器。使用输出缓冲,您的HTML存储在一个变量中,并在脚本末尾作为一个片段发送到浏览器。 Web开发人员的输出缓冲优势 单独打开输出缓冲可减少下载和呈现HTML所需的时间,因为在PHP处理HTML时,不会将其分段发送给浏览

  • 我来这里是为了消除专家们对opengl的一些困惑。我感谢你的帮助! 顶点着色器代码看起来像 所以,这是我的理解。GLVertexAttributePointer的目的是定义顶点缓冲区对象中的数据格式。因此,在vbo中,它按如下方式存储数据 所以,我们有两条glVertex AttribPointer线,因为我们在顶点着色器中定义了两个变量。所以基本上我们定义了这两个变量指向什么。因此,第一个glV

  • 我试图使用FileInputStream将一个文件读入数组,一个~800KB的文件读入内存大约需要3秒钟。然后,我尝试了相同的代码,只是将FileInputStream包装到BufferedInputStream中,耗时约76毫秒。为什么使用BufferedInputStream一个字节一个字节地读取文件要快得多,即使我仍在一个字节一个字节地读取它?下面是代码(其余代码完全无关)。请注意,这是“快