Skip to content

Instantly share code, notes, and snippets.

@elexfreeman
Created June 2, 2019 08:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elexfreeman/d67ab0aee98c89fa7da5c0231cf7f6d5 to your computer and use it in GitHub Desktop.
Save elexfreeman/d67ab0aee98c89fa7da5c0231cf7f6d5 to your computer and use it in GitHub Desktop.
<?php
class SeekableFileReader {
/* указатель на файл */
private $handle;
/* длина файла (кол-во строк)*/
private $fileLength = 0;
/* массив позиций для ф-и fseek() */
private $seekArr = [];
/* текущая позиция */
private $position = 0;
function __construct($filename) {
$this->handle = fopen($filename, "r");
$this->getFileLength();
}
function __destruct() {
$this->close();
}
/* вычисляет длинну файла */
private function getFileLength() {
$this->seekArr[] = ftell($this->handle);
while (fgets($this->handle) !== false) {
/* записывам указатель на позицию */
$this->seekArr[] = ftell($this->handle);
/* записываем длинну */
$this->fileLength++;
}
}
/* считывает строку из текстового файла */
private function getRow() {
if(!feof($this->handle)) {
return trim(fgets($this->handle));
} else {
return false;
}
}
public function getSeekArr(){
return $this->seekArr;
}
public function close(){
fclose($this->handle);
}
public function seek($position)
{
if (!$this->valid($position)) {
throw new \OutOfBoundsException("invalid seek position ($position)");
}
$this->position = $position;
}
public function rewind()
{
$this->position = 0;
}
public function current()
{
fseek($this->handle, $this->seekArr[$this->position]);
return $this->getRow();
}
public function key()
{
return $this->position;
}
public function next()
{
if($this->position < $this->fileLength-1) $this->position++;
}
public function prev()
{
if($this->position != 0) $this->position--;
}
public function valid($position)
{
return (($position < $this->fileLength) && ($position >= 0));
}
}
/* tests */
$file = new SeekableFileReader('./package.json');
print_r($file->current()."\r\n");
$file->next();
$file->next();
$file->next();
$file->next();
$file->next();
print_r($file->current()."\r\n");
$file->prev();
$file->prev();
$file->prev();
$file->prev();
$file->prev();
$file->prev();
$file->prev();
print_r($file->current()."\r\n");
$file->seek(1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment