Так как я еще не нашел лучший ответ, я решил использовать блокировку в рамках своего приложения для синхронизации доступа к коду, который делает этот запрос.
Это должно работать:
$line = '';
$f = fopen('data.txt', 'r');
$cursor = -1;
fseek($f, $cursor, SEEK_END);
$char = fgetc($f);
/**
* Trim trailing newline chars of the file
*/
while ($char === "\n" || $char === "\r") {
fseek($f, $cursor--, SEEK_END);
$char = fgetc($f);
}
/**
* Read until the start of file or first newline char
*/
while ($char !== false && $char !== "\n" && $char !== "\r") {
/**
* Prepend the new char
*/
$line = $char . $line;
fseek($f, $cursor--, SEEK_END);
$char = fgetc($f);
}
echo $line;
Используйте fseek . Вы ищите последнюю позицию и ищите ее назад (используйте ftell , чтобы указать текущую позицию), пока не найдете «\ n».
$fp = fopen(".....");
fseek($fp, -1, SEEK_END);
$pos = ftell($fp);
$LastLine = "";
// Loop backword util "\n" is found.
while((($C = fgetc($fp)) != "\n") && ($pos > 0)) {
$LastLine = $C.$LastLine;
fseek($fp, $pos--);
}
ПРИМЕЧАНИЕ: Я не тестировал. Вам может потребоваться некоторая корректировка.
ОБНОВЛЕНИЕ: Спасибо Синтаксическая ошибка
за указание на пустой файл.
: - D
ОБНОВЛЕНИЕ2: Исправлена еще одна синтаксическая ошибка, отсутствует точка с запятой в $ LastLine = ""
Вы ищете функцию fseek . В разделе комментариев есть рабочие примеры того, как читать последнюю строку файла.
Если вы знаете верхнюю границу длины строки, вы можете сделать что-то вроде этого.
$maxLength = 1024;
$fp = fopen('somefile.txt', 'r');
fseek($fp, -$maxLength , SEEK_END);
$fewLines = explode("\n", fgets($fp, $maxLength));
$lastLine = $fewLines[count($fewLines) - 1];
В ответ на редактирование : fopen просто получает дескриптор файла (т.е. убедитесь, что он существует, процесс имеет разрешение, позволяет операционной системе узнать, что процесс использует файл и т. д.). В этом примере в память будут прочитаны только 1024 символа из файла.
Ваша проблема похожа на эта
Лучший способ избежать загрузки всего файла в память выглядит так:
$file = escapeshellarg($file); // for the security concious (should be everyone!)
$line = `tail -n 1 $file`;
Можно ли было оптимизировать это с другой стороны? Если это так, просто позвольте приложению ведения журнала всегда записывать строку в файл при ее усечении (т.е.> вместо >>)
Некоторая оптимизация может быть достигнута путем «угадывания», но просто откройте файл и со средней строкой журнала width можно было догадаться, где будет последняя строка. Перейдите в эту позицию с помощью fseek и найдите последнюю строку.
Я бы использовал file (), который считывает файл в массив, переворачивает массив и получает первый элемент или выталкивает массив:
$ last_line = array_pop (file ($ filename) );
Если вам нужна производительность, попробуйте открыть файл и использовать указатель файла для перехода к нему.