Считайте последнюю строку из файла

Так как я еще не нашел лучший ответ, я решил использовать блокировку в рамках своего приложения для синхронизации доступа к коду, который делает этот запрос.

31
задан Lightness Races with Monica 1 July 2011 в 21:46
поделиться

7 ответов

Это должно работать:

$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;
45
ответ дан 27 November 2019 в 21:46
поделиться

Используйте 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 = ""

19
ответ дан 27 November 2019 в 21:46
поделиться

Вы ищете функцию fseek . В разделе комментариев есть рабочие примеры того, как читать последнюю строку файла.

6
ответ дан 27 November 2019 в 21:46
поделиться

Если вы знаете верхнюю границу длины строки, вы можете сделать что-то вроде этого.

$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 символа из файла.

4
ответ дан 27 November 2019 в 21:46
поделиться

Ваша проблема похожа на эта

Лучший способ избежать загрузки всего файла в память выглядит так:

$file = escapeshellarg($file); // for the security concious (should be everyone!)
$line = `tail -n 1 $file`;
1
ответ дан 27 November 2019 в 21:46
поделиться

Можно ли было оптимизировать это с другой стороны? Если это так, просто позвольте приложению ведения журнала всегда записывать строку в файл при ее усечении (т.е.> вместо >>)

Некоторая оптимизация может быть достигнута путем «угадывания», но просто откройте файл и со средней строкой журнала width можно было догадаться, где будет последняя строка. Перейдите в эту позицию с помощью fseek и найдите последнюю строку.

0
ответ дан 27 November 2019 в 21:46
поделиться

Я бы использовал file (), который считывает файл в массив, переворачивает массив и получает первый элемент или выталкивает массив:

$ last_line = array_pop (file ($ filename) );

Если вам нужна производительность, попробуйте открыть файл и использовать указатель файла для перехода к нему.

-3
ответ дан 27 November 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: