问题
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