Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php // http://stackoverflow.com/questions/34490225/read-last-n-lines-of-csv-file-in-php
- // include __DIR__ .'/__bootstrap__.php';
- define('SOURCE_CSV_FILE', 'P:/temp' .'/test.csv');
- $reqdlastLines = 125; // how many lines line we want
- $estLineLen = 1024; // guess at the line length
- $avgLineCnt = 20; // number of lines to read to estimate the length
- $avgLineCntStartPos = 10; // number of lines to skip at the start of the file
- $avgLineLen = -1; // measured line length from file records
- /* --------------------------------------------------------------------------
- * Output array...
- */
- $lastRecords = array();
- /* --------------------------------------------------------------------------
- * The source file:
- * o Information
- * o the actual file handle
- */
- $finfo = new SplFileInfo(SOURCE_CSV_FILE);
- $file = fopen(SOURCE_CSV_FILE, 'rb');
- /* ---------------------------------------------------------------------------
- * Get an estimate of the average line length
- */
- // skip first few records...
- for ($recNo = $avgLineCntStartPos; $recNo > 0; $recNo--) {
- $ignore = fgets($file);
- }
- // estimate the record length based on about 20 records...
- $totLen = 0;
- $recCnt = 0;
- for ($recNo = $avgLineCnt; $recNo > 0; $recNo--, $recCnt ++) {
- $rec = fgets($file);
- $totLen += strlen($rec);
- }
- // get the average line length
- $avgLineLen = max($estLineLen, intval($totLen / $recCnt));
- /* ---------------------------------------------------------------------------
- * Position the file pointer to the start of a record near the end of the file
- */
- // how far from the end of the file we should be...
- $seekPos = $avgLineLen * $reqdlastLines;
- $allOk = fseek($file, $seekPos * -1, SEEK_END); // Must be *negative* position
- // now find the start of the next line...
- // by finding first none control character...
- $readCh = chr(0);
- $readChCnt = 0;
- while ($readCh !== false && $readCh < chr(32)) {
- $readCh = fgetc($file);
- $readChCnt++;
- if ($readChCnt > $avgLineLen) { // what happened?
- die('looking for a record: read characters: '. $readChCnt);
- }
- }
- // and the read rest of this record to get to get to the start of the next record...
- $rec = fgets($file);
- /* ---------------------------------------------------------------------------
- * Now we start processing records... yeah!
- *
- * There needs to $reqdLastLines and no more...
- */
- while (!feof($file)) {
- $record = fgetcsv($file);
- if ($record === false) { // end of the file - 'belt and braces'
- break;
- }
- // ensure there are 'required last records' in the array an no more...
- if (count($lastRecords) >= $reqdlastLines) {
- array_shift($lastRecords); // lose earliest record
- }
- $lastRecords[] = $record;
- }
- // we are done...
- fclose($file);
- /* ---------------------------------------------------------------------------
- * Process the last records...
- *
- * Write to file etc. Here I just dump them
- */
- // statistics..
- var_dump($avgLineLen, $seekPos, $finfo->getSize(), $lastRecords);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement