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.