對於大文件只獲取部分數據頗有用php
1.使用ftell函數能夠獲取當前指針的字節位置
2.使用fseek函數能夠直接定位到指定的位置
3.讀取指定字節的數據就能夠部分獲取文件內容了app
<?php class FileStream { private $fp = null; private $mode = 'r'; private $context = null; private $readonly = false; private $writeonly = false; private $appendMode = false; public function __construct($file, $mode = 'r', $context = null) { $mode = trim($mode); if (isset($mode[0])) { $this->mode = strtolower($mode); } if ($context) { $this->context = $context; $this->fp = fopen($file, $mode, false, $this->context); } else { $this->fp = fopen($file, $mode); } if (!$this->fp) { throw new Exception('can not open ' . $file); } if ($this->mode == 'r') { $this->readonly = true; } elseif ($this->mode == 'w') { $this->writeonly = true; } elseif ($this->mode[0] == 'a') { $this->appendMode = true; } } public function __destruct() { $this->close(); } public function close() { if (!$this->fp) { fclose($this->fp); $this->fp = null; } } public function read($size) { if ($this->writeonly) { throw new Exception('write only'); } if (!$this->fp) { throw new Exception('stream already closed'); } $buf = fread($this->fp, $size); if ($buf === false) { throw new Exception('read failed'); } return $buf; } public function readLine() { if ($this->writeonly) { throw new Exception('write only'); } if (!$this->fp) { throw new Exception('stream already closed'); } return fgets($this->fp); } public function readAll() { if ($this->writeonly) { throw new Exception('write only'); } if (!$this->fp) { throw new Exception('stream already closed'); } $buf = ''; while (true) { $s = fread($this->fp, 8192); if ($s === false) { throw new Exception('read failed'); } if (!isset($s[0])) { break; } $buf .= $s; } return $buf; } public function write($data) { if ($this->readonly) { throw new Exception('read only'); } if (!$this->fp) { throw new Exception('stream already closed'); } if (fwrite($this->fp, $data) === false) { throw new Exception('write failed'); } } public function tell() { if ($this->appendMode) { throw new Exception('tell can not work on appendmode'); } if (!$this->fp) { throw new Exception('stream already closed'); } $p = ftell($this->fp); if ($p === false) { throw new Exception('tell failed'); } return $p; } public function seek($position) { if ($this->appendMode) { throw new Exception('seek can not work on seekmode'); } if (!$this->fp) { throw new Exception('stream already closed'); } if (fseek($this->fp, $position) !== 0) { throw new Exception('seek failed'); } } } $stream=new FileStream("1.log"); $start=0; $end=0; //獲取開始和結束的字節位置 while($ln=$stream->readLine()){ if($ln=="3333333333333\r\n"){ $start=$stream->tell(); } if($ln=="5555555555555\r\n"){ $end=$stream->tell(); } } var_dump($start,$end); //直接定位到開始的字節位置 $stream->seek($start); //讀取指定字節數的數據 $res=$stream->read($end - $start); var_dump($res);
1.log的內容函數
2.獲取部分結果this