PHP code example of sorelvi / stream-reader

1. Go to this page and download the library: Download sorelvi/stream-reader library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

sorelvi / stream-reader example snippets


use Sorelvi\StreamReader\Reader;
use Sorelvi\StreamReader\Enum\Preset;
use Sorelvi\StreamReader\Exception\StreamReaderException;

try {
    // 1. Create a reader for a UTF-8 file
    $reader = Reader::createForFile('/path/to/huge_dump.sql');

    // Optional: Adjust chunk size (default is 64KB)
    $reader->setChunkLength(8192); // 8KB

    // 2. Iterate cleanly
    foreach ($reader->readChunk() as $chunk) {
        // $chunk is guaranteed to end on a valid character boundary
        // e.g. send to database or parse CSV line
        process_data($chunk);
    }
} catch (StreamReaderException $e) {
    // Handles IO errors, corrupted streams, and encoding violations
    error_log('[' . $e->getCode() . '] ' . $e->getMessage());
}

use Sorelvi\StreamReader\Reader;

$sql = "INSERT INTO ... 🚀"; // String with emojis
$reader = Reader::createForString($sql);

foreach ($reader->readChunk() as $chunk) {
    echo $chunk;
}

$reader = Reader::createForString('Hello World');
$reader->setChunkLength(2); // default: 2 bytes

$first  = $reader->readChunk(1)->current(); // 'H'  — one-off override
$second = $reader->readChunk()->current();  // 'el' — uses default 2

use Sorelvi\StreamReader\Reader;
use Sorelvi\StreamReader\StreamCompletenessEstimatorFactory;
use Sorelvi\StreamReader\Enum\Preset;
use Sorelvi\StreamReader\HandleContext;

// 1. Prepare resources
$inputFile = fopen('data.csv', 'rb');
$context = new HandleContext();

// 2. Create the specific estimator
$estimator = StreamCompletenessEstimatorFactory::create(Preset::UTF16LE);

// 3. Instantiate Reader with explicit dependencies
$reader = new Reader($inputFile, $estimator, $context);

foreach ($reader->readChunk() as $chunk) {
    // ...
}

use Sorelvi\StreamReader\Reader;
use Sorelvi\StreamReader\HandleContext;
use Sorelvi\StreamReader\Enum\Preset;

// Step 1: Read some data
$context = new HandleContext();
$reader = Reader::createForFile('large.log', $context, Preset::UTF16);

foreach ($reader->readChunk() as $chunk) {
    process($chunk);
    if (should_pause()) {
        break;
    }
}

// Step 2: Save context
$state = $context->toArray();
save_to_db($state);

// --- Later ---

// Step 3: Resume
$newContext = HandleContext::fromArray(load_from_db());

// The reader will automatically seek to the correct position
$reader = Reader::createForFile('large.log', $newContext, Preset::UTF16);

// Auto-detect BOM
$reader = Reader::createForFile('export_utf16.csv', null, Preset::UTF16);

// Or specify explicitly
$reader = Reader::createForFile('export_utf16le.csv', null, Preset::UTF16LE);

use Sorelvi\StreamReader\Stream;
use Sorelvi\StreamReader\Reader;
use Sorelvi\StreamReader\StreamCompletenessEstimatorFactory;
use Sorelvi\StreamReader\Enum\Preset;

$socket = fsockopen('tcp://example.com', 9000);

$stream = new Stream($socket);
$stream->setMaxEmptyAttempts(50);          // max retries on empty reads (default: 20)
$stream->setAttemptsDelayMicroseconds(5000); // delay between retries in µs (default: 10000)

$estimator = StreamCompletenessEstimatorFactory::create(Preset::UTF8);
$reader = new Reader($stream, $estimator);

foreach ($reader->readChunk() as $chunk) {
    // ...
}

use Sorelvi\StreamReader\EstimatorInterface;
use Sorelvi\StreamReader\HandleContext;
use Sorelvi\StreamReader\Reader;

class MyProtocolEstimator implements EstimatorInterface
{
    public function handle(string $buffer, HandleContext $context): int
    {
        // Return 0 if the buffer ends on a complete unit,
        // or N > 0 to request N more bytes before yielding.
        $remainder = strlen($buffer) % 7; // 7-byte fixed records
        return $remainder ? 7 - $remainder : 0;
    }

    public function getMaxAddReadBytes(): int
    {
        return 6; // max bytes ever requested in one handle() call
    }
}

$reader = Reader::createForFile('records.bin', null, new MyProtocolEstimator());

use Sorelvi\StreamReader\StreamInterface;

class MyCustomStream implements StreamInterface
{
    public function isEndOfStream(): bool { /* ... */ }
    public function read(int $length): string { /* ... */ }
    public function skip(int $offset): void { /* ... */ }
    public function getCurrentPosition(): int { /* ... */ }
}

$reader = new Reader(new MyCustomStream(), $estimator);

use Sorelvi\StreamReader\Exception\StreamDamaged;
use Sorelvi\StreamReader\Exception\ErrorCode;

try {
    foreach ($reader->readChunk() as $chunk) { /* ... */ }
} catch (StreamDamaged $e) {
    match ($e->getCode()) {
        ErrorCode::INCOMPLETE_SEQUENCE_AT_EOF->value  => handleTruncated(),
        ErrorCode::ORPHAN_CONTINUATION_BYTE->value    => handleCorrupted(),
        ErrorCode::INVALID_START_BYTE_DETECTED->value => handleInvalid(),
        default => throw $e,
    };
}