Cytat(Pilsener @ 22.09.2010, 11:28:26 )

Musisz użyć fseek by poruszać się po pliku, już raz odpowiadałem na takie pytanie:
http://forum.php.pl/index.php?showtopic=13...st&p=698149Podane przez ciebie rozwiązanie ma sens (i je znam) ale ma jednego buga - co jeśli linia ma zmienna długość od 10 do 400B? ;]
Przekopałem już sporo kodu w internecie i chyba tylko to co udało mi się znaleźć w swoich zbiorach działa w każdych warunkach (szukając \n).
edit:
W manie dokopałem się też do innego sposobu realizacji. Ma ograniczenie do 4KB/linię (chyba że się mylę w interpretacji kodu to proszę mnie poprawić). Jest nieco szybsza (~18%) od mojej.
Delikatnie zmodyfikowałem aby nie pluło tyle notice oraz domyślną ilość linii dla zgodności z *nixowym tailem (10 zamiast 100)

function unix_tail($file, $numLines = 10)
{
$chunk = 4096;
$data = "";
for ($len = 0; $len < $max; $len += $chunk) {
$seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
fseek($fp, ($len + $seekSize) * -1
, SEEK_END
); $data = fread($fp, $seekSize) . $data;
preg_match("!(.*?\n){".($numLines)."}$!", $data, $match); return $match[0];
}
}
return $data;
}
edit2:
Pospieszylem się ... moja funckcja zawiera błąd powodujący odwrócenie kolejności linii.
edit3:
Jak widać zagadnienie taila w php nie jest takie banalne jak mogło by się wydawać. Po testach pokazana wyżej funkcja robi błędy!
Nie starałem się jej debugować jednakże czasami zwraca 3 linie zamiast 4, czasami pusty string (wtf?!).
Poprawiłem nieco moją funkcję dodając zmieniając return $ret na implode("\n", array_reverse(explode("\n", $ret))) [tak na szybko] i działa względnie poprawnie ... chociaż też nie do końca.
Czy ktokolwiek jest w stanie pokazać dlaczego ni jedna ni druga funkcja nie działają w 100% poprawnie? Ew. czy ktoś zna C i może powiedzieć jak robi to oryginalny tail?
edit4:
Udało mi się znaleźć funkcję która działa i jest 3x szybsza od mojej.
Naśladuje praktycznie w 100% taila.
function unix_tail($file, $num_to_get=10)
{
$chunklen = 4096;
if($position-$chunklen <= 0
)fseek($fp,0
); else fseek($fp, $position-$chunklen); $data="";$ret="";$lc=0;
while($chunklen > 0)
{
$data = fread($fp, $chunklen); for($i=$dl-1;$i>=0;$i--){
if($data[$i]=="\n"){
if($lc==0 && $ret!="")$lc++;
$lc++;
if($lc>$num_to_get)return $ret;
}
$ret=$data[$i].$ret;
}
if($position-$chunklen <= 0 ){
$chunklen=$chunklen-abs($position-$chunklen); }else fseek($fp, $position-$chunklen); $position = $position - $chunklen;
}
return $ret;
}