2010-08-27 12 views
14

Ho uno script che analizza file di grandi dimensioni riga per riga. Quando incontra un errore che non può gestire, si arresta, segnalandoci l'ultima riga analizzata.fseek() per riga, non per byte?

Questo è davvero il migliore/solo modo di cercare una linea specifica in un file? (. fseek() non è utilizzabile nel mio caso)

<?php 

for ($i = 0; $i < 100000; $i++) 
    fgets($fp); // just discard this 

Non ho un problema con questo, è abbastanza veloce - si sente solo un po 'sporco. Da quello che so del codice sottostante, non immagino ci sia un modo migliore per farlo.

risposta

30

Un modo semplice per cercare ad una linea specifica di un file è quello di utilizzare la classe SplFileObject, che supporta la ricerca di un numero di riga (seek()) o byte di offset (fseek()).

$file = new SplFileObject('myfile.txt'); 
$file->seek(9999);  // Seek to line no. 10,000 
echo $file->current(); // Print contents of that line 

Sullo sfondo, seek() fa proprio ciò che il vostro codice PHP ha fatto (tranne, in codice C).

+0

Bello! Ci sono passato un po 'di tempo fa e ho iniziato a usarlo. – jasonbar

+0

In questo caso, la ricerca leggerà direttamente la riga 10.000, senza percorrere le righe 1 - 9.999 per raggiungere la linea indicata? – Googlebot

+0

@Ali: no, come pensi che sappia dove iniziano le linee? Legge attraverso il file. Ci sono altre alternative se si vuole cercare direttamente una linea ma coinvolgono sistemi potenzialmente complessi per tenere traccia di dove iniziano le linee nel file. – salathe

4

Se si dispone solo del numero di riga, non c'è altro metodo per trovare la linea. I file non sono basati su linee (o persino su caratteri), quindi non c'è modo di passare semplicemente a una linea specifica in un file.

Ci potrebbero essere altri modi di leggere le righe nel file che potrebbero essere leggermente più veloci, come leggere i pezzi più grandi del file in un buffer e leggere le righe da quello, ma si può solo sperare che sia un po ' Più veloce. Qualsiasi metodo per trovare una linea specifica in un file deve ancora leggere tutti i dati fino a quella linea.

+0

Sì, ho pensato tanto. In qualche modo ho pensato che un bel 'fseekbyline()' che era solo un wrapper per il codice C mi avrebbe fatto sentire meglio. eh. – jasonbar

0

Se ho capito correttamente, si desidera cercare la linea specifica in qualche punto dopo aver trovato un errore. In questo caso, probabilmente memorizzi o stampi il numero di riga della riga errata da qualche parte, a seconda di cosa intendi con "notifica".

meno che non si davvero significa che non è possibile utilizzare fseek() *, cosa si può fare è anche negozio/stampa la posizione nel file dove inizia la linea di male. Quindi puoi fseek().

* Come, in tal caso, sarebbe fseekbyline() utilizzabile se esistesse?

2

So che è in ritardo per la pubblicazione, ma può aiutare alcune ppl ho fatto una funzione come fseekbyline un giorno ...

function GoToLine($handle,$line) 
{ 
    fseek($handle,0); // seek to 0 
    $i = 0; 
    $bufcarac = 0;      

    for($i = 1;$i<$line;$i++) 
    { 
    $ligne = fgets($handle); 
    $bufcarac += strlen($ligne); // in the end bufcarac will contains all caracters until the line 
    } 

    fseek($handle,$bufcarac); 
} 

non esiste un sistema di errore, se si vuole passare alla riga < 1 o 203 ma il file è vuoto ... non otterrai nulla di buono.

stesso se si vuole andare fuori EOT

+0

Nel momento in cui PHP ha attraversato il ciclo for, il puntatore sarà dove si desidera.Basta chiamare fgets ($ handle) per inserire il ciclo for, ed è possibile evitare il caricamento della memoria nelle variabili $ bufcarac e $ ligne. – Gregory

1
rewind($handle); 
while($i=0; $i<$desired_line; i++) 
    fgetcsv($handle, 1000, ",") 

Questo funziona per me mentre ho bisogno di riavvolgere su una linea specifica più volte nel mio script.

Non sono sicuro se questo consuma memoria o velocità, ma fa il trucco.

+0

Questo è breve e al punto. Sebbene fgetcsv sia specifico per i file CSV piuttosto che per qualsiasi file di testo. È utile per me almeno. – Gregory

Problemi correlati