Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Czytanie końca pliku
Forum PHP.pl > Forum > PHP
mkozak
Mam taki przypadek:

Po stronie przeglądarki chcę wyświetlić ostatnie linie pliku log serwera. Plik log-ów naturalnie jest textowy i ma wielkość plus nieskończoność (nieskończoność do granic miejsca na macierzy).

Można co prawda otwierać cały plik i go czytać i czytać, ale przy większym pliku jest bezsensu (pamięć i wydajność). Potrzebuje jedynie ostatnie 10 linii pliku.

macie jakiś szybki dobry pomysłquestionmark.gif?
Ociu
file + end
erix
Cytat
(nieskończoność do granic miejsca na macierzy).

~ociu, tym na pewno osiągnie, co trzeba... tongue.gif

Co do wątku - najlepiej wywołać polecenie powłoki, a jeśli już koniecznie musi być via PHP, to: http://pl.lmgtfy.com/?q=tail+php
mkozak
Pyszna rada.

File wrzuca 120MB do array zjadając momentalnie całą pamięci udostępnioną skryptowi, żeby wczytać ostatnie 10 linijek.

Ktoś ma lepszy pomysł?

Cytat(erix @ 5.01.2010, 15:35:03 ) *
Co do wątku - najlepiej wywołać polecenie powłoki, a jeśli już koniecznie musi być via PHP, to: http://pl.lmgtfy.com/?q=tail+php


Z takim podejściem to równie dobrze można zamknąć to forum i dać wszystkim do zrozumienia, żeby szukać wszędzie indziej tylko nie tu.

Jest pełno class i innego G w necie do symulowania taila, ale czy nie da się tego zrobić jakąś funkcją w PHP??
Albo przynajmniej kombinacją funkcji?questionmark.gif

Już całkiem blisko byłem przy file_get_contents(), gdzie można podać offset i maxlenght.

Można odczytać rozmiar pliku i .... i tu jest właśnie bug, bo funkcja przyjmuje wartość liczbową odpowiadającą kolejnemu znakowi w pliku (np 1400 znak w pliku).

Tylko, że wpisy mają różną długość, ciężko trafić w początek 10 linji od końca.

Najpierw by trzeba było policzyć ilość znaków w pliku - też słaby pomysł.

Ktoś jeszcze ma jakiś pomysłquestionmark.gif
Pilsener
File? Człowiek ma problem, by przekopać się przez plik a co dopiero wczytać go do pamięci. Po co ładować plik do pamięci jako tablicę, gdy chcemy odczytać tylko jego koniec?
  1. $uchwyt = fopen($pliczek,'r'); //otwieramy plik
  2. fseek($uchwyt,-100,SEEK_END); //ustawiamy wskaźnik np. 100 bajtów od końca pliku
  3. while(!feof($uchwyt)){ //parsujemy plik od podanego miejsca
  4. $linia = fgets($uchwyt);
  5. echo $linia.'<br />';
  6. }
  7. fclose($uchwyt);
- pisane z palca, ale powinno działać

Musisz mniej więcej obliczyć, ile bajtów od końca to będzie 10 linijek, następnie przeparsować ten fragment i wrzucić linijki do tablicy, z której po odwróceniu odetniesz (array_slice z tego co pamiętam) każdy index większy niż 10.

Edit: w manualu pełno przykładów na różne taile:
http://pl2.php.net/manual/pl/function.fseek.php
erix
Cytat
Z takim podejściem to równie dobrze można zamknąć to forum i dać wszystkim do zrozumienia, żeby szukać wszędzie indziej tylko nie tu.

Ciężko kliknąć 5. wynik? Naprawdę ciężko?

Cytat
ale czy nie da się tego zrobić jakąś funkcją w PHP??

Nie. Gdyby była, podałbym link do manuala.

Cytat
Ktoś ma lepszy pomysł?

tail wykonane jako polecenie powłoki.
mkozak
Dzięki Pilsener

GR8 Success

  1. function tail($file, $ile_linijek = 10){
  2. $t_out = array();
  3. $licznik = 0;
  4. // Zapas srednio 128 bajtow na linijke
  5. $ile_bajtow = -128 * $ile_linijek;
  6.  
  7. $uchwyt = fopen($file,'r'); //otwieramy plik
  8.  
  9. fseek($uchwyt,$ile_bajtow,SEEK_END); //ustawiamy wskaźnik np. 100 bajtów od końca pliku
  10.  
  11. while(!feof($uchwyt)){ //parsujemy plik od podanego miejsca
  12. $linia = fgets($uchwyt);
  13. $t_echo[] = $linia;
  14. $licznik++;
  15. }
  16. fclose($uchwyt);
  17.  
  18. //zdejmij ostatnia linijke jezeli pusta
  19. if($t_echo[$licznik] == ''){
  20. array_pop($t_echo);
  21. }
  22.  
  23. //Odlicz ile linijek
  24. for($i = 0; $i<$ile_linijek; $i++){
  25. $t_out[] = array_pop($t_echo);
  26. }
  27.  
  28. return $t_out;
  29.  
  30. }


Cytat(erix @ 5.01.2010, 15:53:24 ) *
Ciężko kliknąć 5. wynik? Naprawdę ciężko?

Nie. Gdyby była, podałbym link do manuala.

tail wykonane jako polecenie powłoki.


Widzę, że ktoś tu tylko nabija ilość postów, zamiast przeprowadzić rzeczową dyskusję....... dry.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.