I needed to stream a txt file (here big xml file) to get nodes blockwise. I couldn't find a shorter way. So i did write this class.
Function: streams a complete file and returns the content between two search strings with their search strings (multi byte safe)
Hope it helps anyone.
PS: It lacks any boolean checks / exception handling for non existing files / read errors.
<?php
class streamFileTxt
{
private $handle;
private $file;
private $file_offset;
private $block;
private $start_string;
private $stop_string;
private $block_size;
public function setArgs($_args)
{
$this->file = $_args['file'];
$this->start_string = $_args['start_string'];
$this->stop_string = $_args['stop_string'];
$this->block_size = $_args['block_size'];
}
public function getNextBlock()
{
$this->openFile();
fseek($this->handle, $this->file_offset);
$start_string_found = false;
$stop_string_found = false;
while (!feof($this->handle))
{
$txt_block = fread($this->handle, $this->block_size);
if (!$start_string_found) {
$strpos = mb_strpos($txt_block, $this->start_string);
if ($strpos !== false)
{
$txt_block = mb_substr($txt_block, $strpos, $this->block_size);
$start_string_found = true;
}
}
if ($start_string_found && !$stop_string_found) {
$strpos = mb_strpos($txt_block, $this->stop_string);
if ($strpos !== false)
{
$removed_block_size = mb_strlen($txt_block) - $strpos;
$txt_block = mb_substr($txt_block, 0, $strpos + mb_strlen($this->stop_string));
$stop_string_found = true;
$this->setFileOffset($removed_block_size);
}
}
if ($stop_string_found) {
$this->closeFile();
return $txt_block;
}
}
$this->closeFile();
return false;
}
private function setFileOffset($removed_block_size)
{
$this->file_offset = ftell($this->handle) - $removed_block_size;
}
private function openFile()
{
$this->handle = fopen($this->file, 'r');
}
private function closeFile()
{
fclose($this->handle);
}
}