Skip to content
Advertisement

SplFileObject + LimitIterator + offset

I have data file with two lines (two lines just for my example, in real, that file can contain millions of lines) and I use SplFileObject and LimitIterator with offseting. But this combination have strange behaviour in some cases:

$offset = 0;
$file = new SplFileObject($filePath);
$fileIterator = new LimitIterator($file, $offset, 100);
foreach ($fileIterator as $key => $line) {
  echo $key;
}

Output is: 01

But with $offset set to 1, output is blank (foreach doesn’t iterate any line).

My data file contain this:

{"generatedAt":1434665322,"numRecords":"1}
{"id":"215255","code":"NB000110"}

What I’m doing wrong?

Thanks

Advertisement

Answer

Required:

Use SplFileObject to process a number of records from:

  • a given start record number
  • for a given number of records or until EOF.

The issue is that SplFileObject gets confused as regards the last record in the file. This prevents it working correctly in foreach loops.

This code uses the SplFileObject and ‘skip records’ and ‘processes records’. Alas, It cannot use foreach loops.

  • Skip a number of records from the start of the file ($offset).
  • Process a given number of records or unit the end of file ($recordsToProccess)

The code:

<?php

$filePath = __DIR__ . '/Q30932555.txt';
// $filePath = __DIR__ . '/Q30932555_1.txt';

$offset = 1;
$recordsToProcess = 100;

$file = new SplFileObject($filePath);

// skip the records
$file->seek($offset);

$recordsProcessed = 0;
while (     ($file->valid() || strlen($file->current()) > 0)
         &&  $recordsProcessed < $recordsToProcess
       ) {
    $recordsProcessed++;
    echo '<br />', 'current: ', $file->key(), ' ', $file->current();
    $file->next();
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement