SplFileObject + LimitIterator + offset

半腔热情 提交于 2021-02-08 15:31:26

问题


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


回答1:


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();
}



回答2:


Reading the related PHP bug 65601 suggests adding the READ_AHEAD flag will fix this. Tested and works as you expected it to.

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


来源:https://stackoverflow.com/questions/30932555/splfileobject-limititerator-offset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!