# file.read()

Read one bounded byte range of the file selected for an active upload.

## Signature

```ts
file.read(offset: number, length: number): Promise<Uint8Array>
```

## Availability

Only on the file object passed to an active upload handler. No global file handle or filesystem path is exposed.

## Parameters

| Parameter | Required | Description |
| --- | --- | --- |
| `offset` | Yes | Integer byte offset >= 0. |
| `length` | Yes | Positive integer byte count, at most 1 MiB (1,048,576 bytes). offset + length must be <= file.size. |

## Return value

Resolves to a Uint8Array containing exactly length bytes.

## Behavior and errors

At most four reads may be in flight per upload. The cumulative requested-byte allowance is four times file.size. Prefer forward streaming. Invalid ranges, exhausted read budget, missing/finished upload, changed/truncated file, or filesystem errors reject. Zero-length reads are invalid even at EOF. Supply integers: malformed non-integral bridge values may be dropped before a rejection can be produced. Do not retain the file object for later uploads.

## Example

```js
// Inside an upload handler; sendChunk is your service-specific implementation.
for (let offset = 0; offset < file.size;) {
  const length = Math.min(1024 * 1024, file.size - offset)
  const bytes = await file.read(offset, length)
  await sendChunk(bytes, offset)
  offset += bytes.byteLength
  context.progress(offset / file.size)
}
```

See [grove.uploads.register()](grove-uploads-register.md).

