# ffi/read-bytes
Read a byte range from native memory into a binary-safe Deft string — NUL
bytes are preserved, unlike `ffi/string`. For buffer resources the range is
bounds-checked.
## Syntax
[ffi/read-bytes $buf $offset $length]
## Parameters
- `$buf` — native resource: a buffer from `ffi/alloc` (bounds-checked), or
another resource whose pointer is read as a raw byte address
(unchecked)
- `$offset` — byte offset (number; negative values clamp to 0)
- `$length` — byte count (number; negative clamps to 0; `0` returns `""`)
## Examples
set buf [ffi/alloc 8] [ffi/write $buf 0 :u8 65] [ffi/write $buf 1 :u8 0] [ffi/write $buf 2 :u8 66] set s [ffi/read-bytes $buf 0 3] # → "A\0B" (length 3, NUL kept) [ffi/read-bytes $buf 4 8] # → %Err{:message "ffi/read-bytes: range exceeds buffer size"} [ffi/read-bytes $buf 0 0] # → "" [ffi/close $buf]
## Returns
A binary-safe string of the copied bytes. `%Err{:message}` for wrong arity,
a non-resource argument, a closed resource, a null pointer, non-numeric
offset/length, a buffer range past the end, or string allocation failure.
Reading through a non-buffer resource performs no bounds checking.
## See Also
`ffi/read`, `ffi/write`, `ffi/alloc`, `ffi/string`, `bytes/len`