Fix unsafe usage of FileChannel.read()

`read()` may return fewer bytes than requested; when this occurred, the old
code would silently return less data than requested, which might cause stream
corruption errors.