[PHP] 使用ftell和fseek函数直接定位文件位置获取部分数据
2023-02-18 15:47:00 时间
对于大文件只获取部分数据很有用
1.使用ftell函数可以获取当前指针的字节位置
2.使用fseek函数可以直接定位到指定的位置
3.读取指定字节的数据就可以部分获取文件内容了
<?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.获取部分结果
相关文章
- elasticsearch之metric聚合
- elasticsearch global 、 filters 和 cardinality 聚合
- elasticsearch 聚合之 date_histogram 聚合
- elasticsearch 之 histogram 直方图聚合
- elasticsearch bucket 之rare terms聚合
- elasticsearch多字段聚合实现方式
- elasticsearch聚合之bucket terms聚合
- 实现fastdfs防盗链功能
- SpringBoot整合fastdfs
- centos7上单机安装fastdfs6.0.9
- 使用SpringBatch读取csv文件
- awk的简单使用
- ThreadLocal的简单理解
- 记录一下MySql update会锁定哪些范围的数据
- mac上使用Vmware Fusion虚拟机配置Centos的静态ip
- drools决策表的简单使用
- drools动态增加、修改、删除规则
- drools执行String规则或执行某个规则文件
- SpringBoot集成drools
- drools执行完某个规则后终止别的规则执行