2014-07-26 24 views
6

Voglio stampare una linea particolare (diciamo 200) di un file in un archivio zip. Sto cercando il seguente:PHP - Cerca nel filehandle che punta al file in zip?

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

ma ho

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 

Se io decomprimere il file e creare il SplFileObject con il parametro "file.txt", funziona bene. È documentato ovunque che la ricerca non funziona per i file zippati? Non sono riuscito a trovarlo O sto facendo qualcosa di sbagliato? Grazie.

+0

La sua domanda mi ha insegnato qualcosa. http://php.net/manual/en/ziparchive.getstream.php Vedo che 'fopen()' richiede protocolli 'zip: //' come quello. Non sono sicuro che il 'SplFileObject' fa. Vedo che stai cercando di riferirti a 'file.txt' in' archive.zip', che sembra cercare nella stessa directory in cui ti trovi attualmente. Mi chiedo perché il 'SplFileObject' non ha' getStream() 'metodo per lavorare con le zip. Il metodo 'open' di ZipArchive' restituisce un oggetto che può usare il suo metodo' getStream' per restituire un puntatore di file per il file specificato come argomento. – PHPglue

risposta

2

Buona domanda. Il comportamento che desideri è chiaramente espresso dalla sintassi che hai usato. Lo considero un bug. Probabilmente potresti segnalarlo a http://bugs.php.net. Lo stream deve essere gestito internamente con no-rewind e cache.

Attenzione! La soluzione con SplFileObject è più che selvaggia.

NoRewind è necessario per disabilitare il riavvolgimento. Quindi è necessario Cache per archiviare il contenuto dello stream internamente e renderlo ricercabile. Poi LimitIterator è necessaria per cercare di linea 200.

Ecco come fare:

$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); 
}