Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Seek in filehandle pointing to file in zip?

Tags:

php

seek

I want to print a particular line (say 200th) of a file in a zip archive. I'm trying the following:

$file = new SplFileObject("zip://archive.zip#file.txt");
$file->seek(200);
echo $file->key() . "\n";
echo $file->current(); 

But I get

PHP Warning:  SplFileObject::seek(): stream does not support seeking in script.php on line 2
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Cannot rewind file zip://archive.zip#file.txt' in script.php:2

If I unpack the file and create the SplFileObject with parameter "file.txt", it works OK. Is it documented anywhere that seeking doesn't work for zipped files? I was unable to find it. Or am I doing anything wrong? Thanks.

like image 990
buff Avatar asked Jul 26 '14 22:07

buff


1 Answers

Good question. The behaviour you want is clearly expressed by the syntax you used. I consider this being a bug. You could probably report it at http://bugs.php.net. The stream should be handled internally with no-rewind and cached.

Be warned! The solution with SplFileObject is more than wild.

NoRewind is needed to disallow rewinding. Then Cache is needed to store the stream content internally and make it seekable. Then LimitIterator is needed to seek to line 200.

Here we go:

$obj      = new SplFileObject("zip://archive.zip#file.txt");
$norewind = new NoRewindIterator($obj);
$caching  = new CachingIterator($norewind);
$limit    = new LimitIterator($caching, 200, 1);

foreach ($limit as $i => $line)
{
    printf("%03d: %s", $i, $line);
}
like image 80
Jens A. Koch Avatar answered Sep 23 '22 11:09

Jens A. Koch