gpt4 book ai didi

java - FileInputStream 逐字节或 block 读取?

转载 作者:行者123 更新时间:2023-12-01 18:44:51 24 4
gpt4 key购买 nike

Why is using BufferedInputStream to read a file byte by byte faster than using FileInputStream? 上提供的 bufferedinputstream(BIS) 比 FileInputStream(FIS) 更快的原因是这样的

With a BufferedInputStream, the method delegates to an overloaded read() method that reads 8192 amount of bytes and buffers them until they are needed while FIS read the single byte

根据我的理解,磁盘是一个“ block 设备”。磁盘始终会读取/写入整个 block ,即使读取请求是针对较小量的数据。不是吗?那么,FIS 和 BIS 都将读取完整的 block 而不是单个字节(如 FIS 所述)。正确的 ?那么 BIS 为何比 FIS 快呢?

最佳答案

InputStream 的 java API 就是这样。具体来说,它有这个方法:

int read() throws IOException

它读取单个字节(它返回一个 int,这样它就可以返回 -1 来指示 EOF)。

因此,如果您尝试从文件中读取单个字节,它会尝试这样做。对于像硬盘这样的 block 设备,它可能会读取整个 block ,然后丢弃除该字节之外的所有内容,因此,如果您调用该 read() 方法 8192 次,它一遍又一遍地读取同一个 block 8192 次,每次都会丢弃 8191 字节并只给出您想要的字节。这样,整个过程读取了6700万字节。哎哟。效率不太高。

考虑到内核、CPU、磁盘等都以 8192 的 block 大小读取,BufferedInputStream(new FileInputStream)new FileInputStream< 之间的性能差异为零如果你使用类似:

byte[] buffer = new byte[8192];
in.read(buffer);

现在,即使是普通的无缓冲 new FileInputStream 也只会从磁盘上读取该 block 一次。

即使您使用单字节形式的 read() ,

BufferedInputStream 也会“在幕后”执行此操作,然后将从该字节数组中向您提供数据接下来的 8191 次调用 read()。这就是 BufferedInputStream 所做的全部事情。

如果您使用的是 read() (一次一个字节)变体(或 read 的字节数组变体,但使用非常小的字节数组),则 BufferedInputStream 有道理。否则,它什么也不做,也没有必要把它放在那里。

NB:据我所知,java 不会猜测磁盘缓冲区大小是多少,只是使用一些合理的缓冲区大小。效果是相同的:如果一次使用一个字节,将文件流包装到缓冲流中,性能可提高 1000 倍以上,如果使用字节数组变体,则没有任何区别。

关于java - FileInputStream 逐字节或 block 读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59857893/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com