Although the underlying stream is already buffered, the extra
BufferedReader wrapper around the SubStream results in a noticeable
performance improvement.
This way all reads performed on a resource data stream are forwarded
to the underlying resource file stream, with the read offsets and
lengths adjusted appropriately.
The old functions/methods still exist, so that they continue to raise
the same exceptions as before (which are different depending on
context), but they now use the same implementation internally.