PHPackages                             wp-php-toolkit/bytestream - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. wp-php-toolkit/bytestream

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

wp-php-toolkit/bytestream
=========================

ByteStream component for WordPress.

v0.8.1(1mo ago)0120.0k↑97386.7%7GPL-2.0-or-laterPHPPHP &gt;=7.2

Since May 20Pushed 1mo agoCompare

[ Source](https://github.com/wp-php-toolkit/bytestream)[ Packagist](https://packagist.org/packages/wp-php-toolkit/bytestream)[ Docs](https://wordpress.github.io/php-toolkit/reference/bytestream.html)[ RSS](/packages/wp-php-toolkit-bytestream/feed)WikiDiscussions trunk Synced 2d ago

READMEChangelogDependencies (3)Versions (49)Used By (7)

   slug bytestream   title ByteStream   install wp-php-toolkit/bytestream   see\_also    filesystem | Filesystem | Back file reads and writes with the same stream primitives.

 zip | Zip | Read and write archive entries one stream at a time.

 httpclient | HttpClient | Process request and response bodies incrementally.

    Composable streaming primitives for reading, writing, transforming, hashing, and compressing byte data. Pull/peek/consume semantics let parsers look ahead with bounded buffering, and deflate, inflate, and checksum filters snap together like Lego.

Why this exists
---------------

[](#why-this-exists)

PHP's native streams are powerful but inconsistent. `fread` on a socket may return short reads with no warning; `stream_filter_append` is awkward to compose; gzip helpers and file handles expose different APIs. The ByteStream component normalizes these behind one small interface — `pull / peek / consume` — so a parser, a hash function, and a deflate filter all see the same shape.

The split between *pull* (buffer up to N bytes) and *consume* (advance past N bytes) is the secret. Parsers can `peek` ahead to detect a record boundary and decide whether to `consume`, while keeping buffer ownership inside the stream.

Read a file in chunks
---------------------

[](#read-a-file-in-chunks)

The canonical loop. `pull(N)` reads up to `N` bytes from the underlying source into an internal buffer and returns how many ended up there; `consume(N)` reads `N` bytes from that buffer and advances past them. The buffer never grows beyond the chunk size you ask for.

```
