# ReadableStreamBYOBReader

The `ReadableStreamBYOBReader` interface is part of the Streams API of Azion Runtime. It reads a byte stream into a buffer that you supply, without copying the data. Use it to move data from sources that deliver it as a series of anonymous bytes, such as files. BYOB stands for "Bring Your Own Buffer". For more information, refer to [ReadableStreamBYOBReader](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader) on MDN Web Docs.

---

## Constructor

The [`ReadableStreamBYOBReader()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader/ReadableStreamBYOBReader) constructor creates and returns a reader for the stream you pass to it:

```javascript
new ReadableStreamBYOBReader(stream)
```

You can also create the reader from the stream: call `getReader()` on a [ReadableStream](/en/documentation/devtools/runtime/api-reference/readable-stream/) and set `mode: 'byob'` in its options. The examples on this page create the stream as a byte stream, with `type: 'bytes'` in its handlers.

---

## Properties

| Property                                                                                     | Type    | Description                                                                                                                                             |
| -------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`closed`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader/closed) | Promise | Fulfills when the stream closes. Rejects when the stream throws an error or when the reader releases its lock. Use it to run code when the stream ends. |

---

## Methods

| Method                                                                                                          | Description                                                                                                                                                                                         |
| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`reader.cancel(reason)`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader/cancel)     | Returns a promise that resolves when the stream is canceled. A call signals that the consumer has lost interest in the stream. The underlying source receives `reason` and can use it or ignore it. |
| [`reader.read(view)`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader/read)           | Takes a view that the stream writes data into, such as a `Uint8Array`. Returns a promise that resolves with the next chunk of the stream, or rejects when the stream is closed or has an error.     |
| [`reader.releaseLock()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader/releaseLock) | Releases the lock of the reader on the stream.                                                                                                                                                      |

---

## Examples

This handler constructs a byte stream that holds 5 bytes, creates a BYOB reader with `getReader()`, and reads the stream into an 8-byte buffer. It returns the class name of the reader and the result of `read()`:

```javascript
export default {
  async fetch(request, env, ctx) {
    const stream = new ReadableStream({
      type: 'bytes',
      start(controller) {
        controller.enqueue(new Uint8Array([1, 2, 3, 4, 5]));
        controller.close();
      },
    });
    const reader = stream.getReader({ mode: 'byob' });
    const { value, done } = await reader.read(new Uint8Array(new ArrayBuffer(8)));
    return Response.json({
      ctor: reader.constructor.name,
      done,
      bytes: Array.from(value),
      byteLength: value.byteLength,
    });
  },
};
```

The function returns these values. The returned view holds the 5 bytes the stream wrote, not the full 8 bytes of the buffer:

```json
{
 "ctor": "ReadableStreamBYOBReader",
 "done": false,
 "bytes": [
  1,
  2,
  3,
  4,
  5
 ],
 "byteLength": 5
}
```

To read a stream chunk by chunk into one buffer, call `read()` again from the result of each read, with a view of the part of the buffer that is still empty. In this sample, `stream` is a byte stream of 10 bytes and `buffer` holds 4,000 bytes:

```javascript
const stream = new ReadableStream({ type: 'bytes', start(c) { c.enqueue(new Uint8Array(10).fill(7)); c.close(); } });
const reader = stream.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(4000);

readStream(reader);

function readStream(reader) {
  let bytesReceived = 0;
  let offset = 0;

  while (offset < buffer.byteLength) {
    // read() returns a promise that resolves when a value has been received
    reader.read(new Uint8Array(buffer, offset, buffer.byteLength - offset))
      .then(function processBytes({ done, value }) {
        // Result objects contain two properties:
        // done  - true if the stream has already given all its data.
        // value - some data. Always undefined when done is true.

        if (done) {
          // There is no more data in the stream
          return;
        }

        buffer = value.buffer;
        offset += value.byteLength;
        bytesReceived += value.byteLength;

        // Read some more, and call this function again
        return reader.read(new Uint8Array(buffer, offset, buffer.byteLength - offset)).then(processBytes);
      });
  }
}
```

---

## Related resources

- [ReadableStream](/en/documentation/devtools/runtime/api-reference/readable-stream.md): The stream that a BYOB reader reads, and how to construct a byte stream.
- [ReadableStreamDefaultReader](/en/documentation/devtools/runtime/api-reference/readable-default-reader.md): The reader that `getReader()` returns when you pass no mode.
- [Response](/en/documentation/devtools/runtime/api-reference/response.md): A response whose `body` stream a reader can consume.
- [Web APIs](/en/documentation/devtools/runtime/api-reference/javascript.md): The other Web APIs that Azion Runtime supports.
