FileInputStream真的没有被封口吗?
fileInputStream
使用此本机方法在用户提供的缓冲区中读取字节。正如我们在实现中看到的那样,用户空间缓冲区确实是用长度max(buf_size,提供的缓冲区长度)
分配的。然后将此缓冲区传递给io_read
。我无法提起此方法的实现,但我很确定这是标准的C缓冲读数。为什么fileInputStream
然后说未掩盖?使用哪些其他缓冲 bufferedReader 使用?
结果:
Benchmark Mode Cnt Score Error Units
StreamIOBenchmark.bisMultiBytes avgt 30 27.640 ± 1.117 ms/op
StreamIOBenchmark.bisSingleBytes avgt 30 400.552 ± 26.921 ms/op
StreamIOBenchmark.fisMultiBytes avgt 30 25.231 ± 1.459 ms/op
StreamIOBenchmark.fisSingleBytes avgt 30 97991.213 ± 5620.685 ms/op
编辑: Benchmarks> Benchmarks> Benchmarks 比较实际差异的 单个字节,因为FIS将对每个字节进行新的系统调用。 HOEWVER,一次读取8K字节时,FIS(FIMSULTIBYTES
)和BIS(bimmultibytes
)的表现非常相似。
FileInputStream
uses this native method to read bytes in a user supplied buffer. As we can see in the implementation, a user-space buffer is indeed allocated with length max(BUF_SIZE, supplied buffer length)
. This buffer is then passed to IO_Read
. I could not pull up the implementation of this method but I am pretty sure this is the standard C buffered reading. Why is FileInputStream
then said to be unbuffered? And what additional buffering is BufferedReader
using?
Edit: Benchmark comparing read times of a 100M file and its results:
Benchmark Mode Cnt Score Error Units
StreamIOBenchmark.bisMultiBytes avgt 30 27.640 ± 1.117 ms/op
StreamIOBenchmark.bisSingleBytes avgt 30 400.552 ± 26.921 ms/op
StreamIOBenchmark.fisMultiBytes avgt 30 25.231 ± 1.459 ms/op
StreamIOBenchmark.fisSingleBytes avgt 30 97991.213 ± 5620.685 ms/op
The real difference is while reading single bytes, as FIS will be making a new system call for each byte. Hoewver, When reading 8k bytes at once, both FIS (fisMultiBytes
) and BIS (bisMultiBytes
) perform pretty similarly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的。真的。
不,不是。本机代码不使用C缓冲I/O。它正在执行
读(2)
呼叫到临时缓冲区。然后,它将数据从临时缓冲区复制到提供byte []
的呼叫者。在我正在查看的Java 11U代码中,临时缓冲区是一个小的堆栈缓冲区,或者是
malloc
'd and free 'd'd 'd在本机
调用期间。OpenJDK Java 11U代码库中的相对路径名是
./ src/java.base/share/share/native/libjava/io_util.c
。查找ReadBytes
方法。 中的本机入口点方法调用的)(这是通过
./ src/java.base/ share/share/natival/libjava/fileinputStream.c .C
是一个acrohandleread
包装read(2)
调用的宏。更新
我刚刚注意到您已经找到了
io_util.c
的Java 8U版本的链接。它的行为与我上面描述的11U代码相同。所以也许您只是误解了您发现的C代码?据说它是“没有被掩盖的”,因为它确实是没有被掩盖的。
您可以通过查看
BufferedReader
的(Java)源代码来查看。提示:与其提出(不正确的)假设有关JVM本机代码实现的工作原理,不如下载并读取OpenJDK源代码。它可供有足够的磁盘空间(1.2GB)下载的人使用。
Yes. Really.
No it isn't. The native code is NOT using C buffered I/O. It is performing a
read(2)
call into a temporary buffer. Then it copies the data from the temporary buffer to the caller suppliedbyte[]
.In the Java 11u code I am looking at, the temporary buffer is either a small on-stack buffer or a larger native heap buffer that is
malloc
'd andfree
'd during thenative
call.The relative pathname in the OpenJDK Java 11u codebase is
./src/java.base/share/native/libjava/io_util.c
. Look for thereadBytes
method. (This is called via a native entry point method in./src/java.base/share/native/libjava/FileInputStream.c
)The
IO_Read
inio_utils.c
is a macro that aliaseshandleRead
which wraps theread(2)
call.UPDATE
I just noticed that you had already found a link to the Java 8u version of
io_util.c
. It behaves the same way as the 11u code that I described above. So maybe you just misread the C code you found?It is "said to be" unbuffered because it really is unbuffered.
You can see that by looking at the (Java) source code for
BufferedReader
.Hint: rather than making (incorrect) assumptions about how the JVM native code implementation works, download and read the OpenJDK source code. It is available for anyone with enough disk space (1.2GB) to download.