Skip to content

Streams

You can use streams by passing a resource to this package like so:

use Innmind\IO\IO;

$stream = IO::fromAmbientAuthority()
    ->streams()
    ->acquire(\STDIN);

Read

$read = $stream->read();

->nonBlocking()

$read = $read->nonBlocking();

This will configure the stream to be non blocking when reading from it. This means that it will return as soon as possible with strings shorter than the expected size.

->toEncoding()

use Innmind\Immutable\Str;

$read = $read->toEncoding(Str\Encoding::ascii);

This changes the encoding used in all Str values returned. By default it's Str\Encoding::utf8.

->watch()

$read = $read->watch();

This makes sure the stream being read is ready, meaning there's data to be read. And it will wait forever until the stream is ready.

This is default behaviour.

->timeoutAfter()

use Innmind\TimeContinuum\Period;

$read = $read->timeoutAfter(Period::second(1));

Like ->watch() it will wait for the stream to be ready before being read, except that if it's not ready within 1 second it will fail the read operation.

->poll()

This is a shortcut to ->timeoutAfter(Period::second(0)). This means that if the stream is not ready right away when read it will fail.

->pool()

$pool = $stream1
    ->pool('a')
    ->with('b', $stream2);

This method allows to combine multiple streams that will be read together.

Here a and b are ids used to reference from which stream the read data comes from. You can use any type you want.

Then you can read available chunks from this pool like this:

use Innmind\Immutable\Pair;

$pool
    ->chunks()
    ->foreach(static fn(Pair $chunk) => match ($chunk->key()) {
        'a' => doSomethingWithStream1($chunk->value()),
        'b' => doSomethingWithStream2($chunk->value()),
    });

->frames()

This is the main way to read data from streams.

use Innmind\IO\Frame;

$frames = $read->frames(Frame::line());

Then you can either read:

$line = $frames
    ->one()
    ->unwrap();

$line is an instance of Innmind\Immutable\Str. ->one() returns an Attempt monad that we ->unwrap() here, meaning that if it fails to read the frame then it will throw an exception.

$lines = $frames
    ->lazy()
    ->sequence();

$lines is a Innmind\Immutable\Sequence<Innmind\Immutable\Str>.

Since the sequence is lazy this means that you may read some lines and then an exception is thrown if it fails to read a line.

See the Frames section to learn how to create frames.

Write

$write = $stream->write();

->sink()

use Innmind\Immutable\{
    Sequence,
    Str,
};

$successful = $write->sink(
    Sequence::of(
        Str::of('chunk 1'),
        Str::of("new line \n"),
        Str::of('chunk 2'),
        Str::of('etc...'),
    ),
);

This will write each Str one after the other to the stream.

$successful is an Attempt monad. It will contain an error if it failed to write one the chunks.

Since the data to write is expressed with a Sequence, you can use a lazy one to write data that may not fit in memory.