2011-12-01 15 views

Odpowiedz

4

Dlaczego po prostu nie używać funkcji obsługi plików i nie podoba mi się w this question? Jest prosty, szybki i bardzo wydajny.

Jeśli koniecznie musi używać SPL, można to zrobić jak ten

$file = new SplFileObject("/path/to/file.txt"); 
$i = 0; 
while (!$file->eof()) { 
    $i++; 
    $file->next(); 
} 
print "file has " . $i . " lines"; 
+0

Użyłem tradycyjnego sposobu czytania plików fopen/fgets, zgodnie z zaleceniami, dzięki. Czasami staram się robić wszystko z klasami, kiedy nie jest to potrzebne. –

+0

Jeśli chcesz wykonywać operacje na plikach w sposób zorientowany obiektowo, to właśnie dlatego istnieje SPL. –

+4

Istnieje również ['iterator_count()'] (http://php.net/iterator_count). – salathe

3

The SplFileObject oferuje itertor, jedna iteracja na linię:

$numberOfLines = iterator_count($file); 

Funkcja iterator_count jest twój przyjaciel, wykonanie przejścia dla ciebie i zwrócenie liczby iteracji.

Można użyć obiektu pliku: SKIP_EMPTY flag, aby nie liczyć pustych linii w tym pliku.

+0

Doskonała odpowiedź, ale w przypadku większego pliku (w tym przypadku 10 MB i 135 000 wierszy) jest ona całkowicie zbyt wolna, a próba zliczenia przy użyciu tej metody powoduje przekroczenie limitu czasu. – Typo

33

Iterowanie po linii za pomocą next() jest uszkodzony w mojej wersji PHP 5.3.7 w systemie Ubuntu.

Również wygląda na zepsutą metodę fseek([any offset], SEEK_END). key() zwraca 0.

Powtarzanie dużych plików przy użyciu seek($lineCount) jest zbyt wolne.

simpliest 5.3.7 sprawdzoną metodą jest

// force to seek to last line, won't raise error 
$file->seek($file->getSize()); 
$linesTotal = $file->key(); 

30000 Liczenie linii wymaga teraz 0.00002 sek i kosztuje około 20 KB pamięci.

Metoda iteracji trwa około 3 sekund.

+0

to jest złe, funkcja seek() będzie szukała numeru linii, podczas gdy getSize() zwróci rozmiar pliku w bajtach. – Twisted1919

+1

Wiem. Po prostu zapewnia, że ​​szukaliśmy linii __all__ (nawet jeśli wszystkie są puste). W najczęstszych przypadkach funkcja seek() będzie trafiać do EOF na numer linii, który zdecydowanie mniejszy jest od liczby bajtów, ale PHP obsługuje go w trybie cichym, zwracając ostatni numer linii. Zgadzam się, to jest brudny hack, ale nie znalazłem żadnego "czystego" sposobu szybkiego policzenia linii. –

+0

działa dobrze. Ale plik ma 99 linii, ale zwraca 98. Czy wiesz, dlaczego? – Bala

12

zgadzam się z Николай Конев na wykorzystaniu seek function jest znacznie szybsze niż chodzenie przez cały pliku linia po linii, ale jak Twisted1919 powiedział podstawie rozmiaru pliku do poszukiwania ostatniego wiersza jest niejasna, więc moja propozycja jest używać PHP_INT_MAX zamiast rozmiaru pliku :

// force to seek to last line, won't raise error 
$file->seek(PHP_INT_MAX); 
$linesTotal = $file->key(); 
Powiązane problemy