2012-03-26 23 views
7

Mi stavo chiedendo se qualcuno di fuori sapeva come farlo in PHP. Sto eseguendo uno script che comporta l'apertura di un file, prendendo le prime 1000 righe, facendo alcune cose con quelle righe, quindi il file php apre un'altra istanza di se stesso per prendere le mille righe successive e così via fino a raggiungere la fine del file . Sto usando splfileobject in modo che possa cercare una determinata linea, il che mi consente di suddividerlo abbastanza bene in 1000 pezzi. Il problema più grande che sto avendo è con le prestazioni. Ho a che fare con file che hanno più di 10.000.000 di righe e mentre fa le prime 10.000 linee o giù di lì abbastanza velocemente, dopo quel punto c'è un enorme rallentamento esponenziale che penso sia giusto dover cercare fino a quel momento.Elimina le prime X righe da un file PHP

Quello che mi piacerebbe fare è leggere le prime mille righe, quindi cancellarle dal file in modo che il mio script legga sempre le prime mille righe. C'è un modo per farlo senza leggere il resto del file in memoria. Altre soluzioni che ho visto riguardano la lettura di ogni riga in un array, quindi la rimozione delle prime voci X, ma con dieci milioni di righe che consumeranno troppa memoria e tempo.

Se qualcuno ha una soluzione o altri suggerimenti che potrebbero velocizzare le prestazioni, sarebbe molto apprezzato.

+0

Si * pensa * che il tempo è in cerca di tempo? – salathe

+0

Ho commentato la riga che itera il contatore di riga in modo che eseguisse sempre il primo 1000 e fosse eseguito in modo esponenziale più veloce.Inoltre, questo rallenta esponenzialmente man mano che procede, l'unica cosa che sta cambiando è la linea che sta cercando. –

+0

La ricerca non dovrebbe richiedere * in modo esponenziale * più tempo. Su che tipo di scala è il rallentamento? – salathe

risposta

1

Sfortunatamente non esiste una soluzione reale perché i file vengono sempre caricati completamente nella memoria principale prima di essere letti.

Tuttavia, ho inviato questa risposta perché questa è una possibile soluzione ma sospetto che non migliori le prestazioni. Correggimi se sbaglio

È possibile utilizzare XML per dividere i file in unità di 1000 righe. E usa DomDocument Class di PHP per recuperare e aggiungere dati. È possibile aggiungere il bambino quando si desidera aggiungere dati e recuperare il primo figlio per ottenere le prime mille righe ed eliminare il nodo se lo si desidera. Proprio come questo:

<document> 
    <part> 
     . . . 
     Thousand lines here 
     . . . 
    </part> 
    <part> 
     . . . 
     Thousand lines here 
     . . . 
    </part> 
    <part> 
     . . . 
     Thousand lines here 
     . . . 
    </part> 
    . 
    . 
    . 
</document> 

altro modo:

Se siete davvero sicuri di infrangere le sezioni in esattamente 1.000 linee perché non salvarlo in un database con ogni 1000 in una riga diversa ? In questo modo si riduce sicuramente il sovraccarico di lettura/scrittura dei file e si migliora la prestazione.

1

Mi sembra che l'obiettivo sia analizzare un'enorme quantità di dati e inserirla in un database? Se è così, non riesco a capire perché è importante lavorare con esattamente 1000 linee?

Penso che mi piacerebbe avvicinarlo leggendo una grande quantità di dati, diciamo 1 MB, in memoria in una sola volta, e quindi scansionare all'indietro dalla fine del blocco in memoria per l'ultima riga che termina. Una volta ottenuto ciò, posso salvare la posizione del file e i dati extra che ho (ciò che rimane dall'ultima riga fino alla fine del blocco). In alternativa, basta resettare il puntatore del file usando fseek() nel punto in cui nel file ho trovato l'ultima riga che termina, facilmente eseguibile con strlen ($ chunk).

In questo modo, tutto quello che devo fare è esplodere il blocco eseguendo un'esplosione ("\ r \ n", $ chunk) e ho tutte le linee che mi servono, in un blocco adeguatamente grande per ulteriori elaborazioni.

L'eliminazione di righe dall'inizio del file non è consigliata. Scambierà un'enorme quantità di dati avanti e indietro sul disco.

Problemi correlati