Java FileInputStream是否未缓冲?为什么BufferedInputStream更快?

Java FileInputStream是否未缓冲?为什么BufferedInputStream更快?,java,io,Java,Io,关于IO,我有两个问题 A.在一个教程和一些StackOverflow答案中,他们声称FileInputStream没有缓冲。这是真的吗? 以下代码使用FileInputStream将数据读入字节数组(1024字节) API中有一行: 公共整数读取(字节b[])引发IOException @参数b:将数据读入的缓冲区 B.如果它们都已缓冲,则它们都将数据放入缓冲区,并从缓冲区中提取数据,正是在哪里使BufferedInputStream比FileInputStream更快? 谢谢的确,Fil

关于IO,我有两个问题

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

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

API中有一行:

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

  • @参数b:将数据读入的缓冲区
B.如果它们都已缓冲,则它们都将数据放入缓冲区,并从缓冲区中提取数据,正是在哪里使
BufferedInputStream
FileInputStream
更快?


谢谢

的确,FileInputStream没有缓冲,但它在读取时提供了有限的缓冲能力

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

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

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

在一个教程和一些StackOverflow答案中,他们声称FileInputStream没有缓冲。这是真的吗

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

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

此循环被中断,因为它假定您总是准确读取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);
    }
}
publicstaticvoidmain(字符串[]args)引发IOException{
try(FileInputStream fis=newfileinputstream(“./fos.txt”);
FileOutputStream fos=新的FileOutputStream(“./copy.txt”)){

字节[]缓冲区=新字节[8 BufferedInputStream有一个内部缓冲区。如果您逐个读取字节,它将不会从底层源流中逐个读取字节,而是分批读取字节,并将最后一批存储在缓冲区中。javadoc是您的朋友。您的基准测试无效-它不遵守编写此类基准测试的任何最佳实践在Java中。我会忽略这些数字。@JBNizet,谢谢,但我们确实可以将varaible
buffer
称为缓冲区,对吗?是的,那又怎么样?这并没有使FileInputStream像BufferdInputStream一样进行缓冲。它只是有一个接受外部缓冲区作为参数的方法。相关:谢谢。它很有帮助。很荣幸有您的支持回答。@BoristheSpider不确定它是否更简单,但我希望它更快。注意:BufferedInputStream仅支持对仍在缓冲区中的数据进行标记/重置。+1
    for (int len; (len = fis.read(buffer))!= -1; )
        fos.write(buffer, 0, len);
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);
    }
}