ByteStreamA buffered binary stream — the one reading/writing surface over every conduit: files ([IO]File.byteStream / create: / append:), sockets (TcpSocket#byteStream or ByteStream.over:), and stdin ([IO]Stdin.byteStream).
Reads are buffered through 16 KiB of read-ahead and *park the task* rather than blocking the scheduler. The read family: read (whatever is available), read: (up to n), readExactly: (n or throw), readUntil: (delimiter framing), readAll (to EOF), peek: (look without consuming). Writes: writeAll: — straight through on a socket, buffered on a file write stream (drained by flush! / close / program exit). For text, wrap it with stringStream.
Streaming (de)compression sugar over the generic codecWrap: (whose codec table lives in src/io_codecs.rs — a new codec is a table entry there plus a one-liner here).
A buffered ByteStream that *consumes* a socket (TcpSocket or TlsSocket): the connection transfers to the stream and the socket is left closed — further ops on it throw. Equivalent to the socket's own byteStream.
Like over:, but scoped: run the block with the stream and close it on every exit path (normal, throw, or cancel); answers the block's value.
Flush any buffered writes and close the stream (idempotent — a second close is a no-op). On a write-codec stream (gzip) this also FINISHES the encoder — the trailer that makes the output valid is written here, so close such a stream deliberately; a failed finish throws. Unread buffered bytes are discarded and further operations throw. Returns nil.
Whether the stream has been closed — including by being consumed into a StringStream.
Wrap the stream in a named codec (see io_codecs.rs) IN PLACE — a read codec transforms every later read, a write codec every later write; answers the receiver. Prefer the sugar (gunzip / gzip). A read codec needs an open, unread read stream; a write codec an open, unwritten file write stream (its close then finishes the encoder). An unknown codec throws an IoError.
([IO]File.open:'logs.gz').byteStream.gunzip.readAll "* the decompressed bytes
Hand any buffered written bytes to the OS now. A no-op on a write-through stream (every socket), so the same code works over a file and a socket. Returns nil.
Wrap this (unread) stream so reads yield gunzipped bytes — the streaming twin of Bytes#decodeGz, for reading .gz/.tar.gz without materializing the decompressed whole. Answers the receiver; concatenated gzip members decode end to end.
([IO]File.open:'big.tar.gz').byteStream.gunzip "* a streaming gunzip source
Wrap this (unwritten) file write stream so writes are gzip-compressed — the streaming twin of Bytes#encodeGz, for writing .gz/.tar.gz without materializing the compressed whole. Answers the receiver. close finishes the encoder (the trailer is written there) — close the stream deliberately; a stream the program leaks is finished for it at exit, best-effort.
([IO]File.create:'big.tar.gz').byteStream.gzip "* a streaming gzip sink
Up to n bytes *without* consuming them — the same bytes remain for the next read. Fills until the buffer holds n bytes (or EOF cuts it short). The tool for looking ahead before deciding how to frame.
Whatever bytes are available right now: drain the buffer, or — when it is empty — wait for one fill from the conduit. Empty Bytes means EOF.
Up to n bytes, POSIX-style: possibly fewer than asked (one fill at most), and empty Bytes at EOF. For exactly-n-or-throw semantics use readExactly:.
Read to EOF and answer everything as one Bytes. The whole remainder is held in memory — for bounded reading of long streams use read: or readUntil:limit: in a loop.
Exactly n bytes, or an IoError (kind #unexpectedEof) if the stream ends first — the reader for length-prefixed framing, where a short read is a protocol error.
Bytes up to and *including* the first occurrence of the delimiter (a String or Bytes; empty throws a ValueError). If the stream ends first, the remainder is returned without it — a result not ending in the delimiter means EOF. For untrusted input prefer readUntil:limit:, which bounds the search.
Like readUntil:, but throws (IoError, kind #limitExceeded) once more than limit bytes are buffered with no delimiter among them — bounding hostile delimiter-less input instead of buffering it without end. EOF still returns the partial remainder.
A text StringStream that *consumes* this byte stream: the connection, any read-ahead, and any pending writes all transfer, and this handle is left closed (further ops on it throw).
Write all of the Bytes — complete or throw. Straight through on a socket stream; on a buffered file write stream it lands in the write buffer, draining in 16 KiB chunks (flush! / close drain the rest). Returns nil.