read
Transfer up to length bytes, writing them into the target buffer array at the specified offset.
Every time read is called, this byte source is partially consumed. It is NOT safe to call this method from multiple threads.
Depending on the implementation of this interface, the actual source of data may stall (e.g. if it is fetching bytes from the network), at which point this method will suspend. If you need blocking behavior, you can of course wrap the call in runBlocking, but you can also consider converting it into an InputStream using toInputStream if you prefer.
It is up to the caller to ensure that offset and length are specified so that data won't attempt to write outside the bounds of the target buffer, or else the code will throw.
Return
the number of bytes read, or -1 to indicate EOF (end of data reached; channel closed; etc.)