note 106594 added to function.fseek
| From: | Anonymous at osu1 dot php dot net | Date: | Mon, 21 Nov 2011 15:43:09 +0000 |
| Subject: | note 106594 added to function.fseek | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-184598@lists.php.net to get a copy of this message | ||
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
/**
* Reads txt-files blockwise
* Usage:
$c_streamFileTxt = new streamFileTxt;
$_args = array(
'file' => 'temporary.xml',
'start_string' => '<Product>',
'stop_string' => '</Product>',
'block_size' => '8192'
);
$c_streamFileTxt->setArgs($_args);
while ($txt_block = $c_streamFileTxt->getNextBlock())
{
// use $txt_block for something
}
*/
class streamFileTxt
{
private $handle;
private $file;
private $file_offset;
private $block;
private $start_string;
private $stop_string;
private $block_size;
/**
* Sett class arguments
* @param array $_args
*/
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'];
}
/**
* Get next textblock within a file
* @param void
* @return string $textblock
*/
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) // while not start start snippet found
{
$strpos = mb_strpos($txt_block, $this->start_string);
if ($strpos !== false)
{
// cut of first left chunk
$txt_block = mb_substr($txt_block, $strpos, $this->block_size);
$start_string_found = true;
}
}
if ($start_string_found && !$stop_string_found) // start snipped found, looking for stop
snippet
{
$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) // stop-snippet found, keep file offset, return
{
$this->closeFile();
return $txt_block;
}
}
$this->closeFile();
return false;
}
/**
* Set current file offset and consider the removed block size
* current file position = current file offset - removed block size
* @param int $removed_block_size
*/
private function setFileOffset($removed_block_size)
{
$this->file_offset = ftell($this->handle) - $removed_block_size;
}
/**
* close current file
* @param void
* @return void
*/
private function openFile()
{
$this->handle = fopen($this->file, 'r');
}
/**
* open file
* @param void
* @return void
*/
private function closeFile()
{
fclose($this->handle);
}
}
----
Server IP: 217.160.235.204
Probable Submitter: 91.9.248.195
----
Manual Page -- http://www.php.net/manual/en/function.fseek.php
Edit -- https://master.php.net/note/edit/106594
Del: integrated -- https://master.php.net/note/delete/106594/integrated
Del: useless -- https://master.php.net/note/delete/106594/useless
Del: bad code -- https://master.php.net/note/delete/106594/bad+code
Del: spam -- https://master.php.net/note/delete/106594/spam
Del: non-english -- https://master.php.net/note/delete/106594/non-english
Del: in docs -- https://master.php.net/note/delete/106594/in+docs
Del: other reasons-- https://master.php.net/note/delete/106594
Reject -- https://master.php.net/note/reject/106594
Search -- https://master.php.net/manage/user-notes.php