Считайте файл, назад линию за линией использующий fseek

Как я читаю файл, назад линию за линией использующий fseek?

код может быть полезным. должен быть кросс-платформенный и чистый php.

заранее большое спасибо

с уважением

Jera

13
задан Justin Johnson 13 July 2010 в 07:08
поделиться

4 ответа

Для полного реверса файла:

$fl = fopen("\some_file.txt", "r");
for($x_pos = 0, $output = ''; fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
    $output .= fgetc($fl);
    }
fclose($fl);
print_r($output);

Конечно, вы хотели построчный реверс...


$fl = fopen("\some_file.txt", "r");
for($x_pos = 0, $ln = 0, $output = array(); fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
    $char = fgetc($fl);
    if ($char === "\n") {
        // analyse completed line $output[$ln] if need be
        $ln++;
        continue;
        }
    $output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : '');
    }
fclose($fl);
print_r($output);

На самом деле, Джонатан Кун дал лучший ответ IMHO выше. Единственные известные мне случаи, когда его ответ не стоит использовать, это если файл или подобные функции отключены через php.ini, но админ забыл о fseek, или при открытии огромного файла просто получить последние несколько строк содержимого, что волшебным образом сэкономит память.

Примечание: Обработка ошибок не включена. И, PHP_EOL не сотрудничал, поэтому я использовал "\n" для обозначения конца строки. Так что вышеописанное может работать не во всех случаях.

8
ответ дан 1 December 2019 в 17:16
поделиться

Вы не можете искать строку за строкой, потому что не знаете, какой длины строки, пока не прочитаете их.

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

6
ответ дан 1 December 2019 в 17:16
поделиться

Если вы собираетесь читать весь файл в любом случае, просто используйте file () , чтобы прочитать файл как массив (каждая строка - это каждый элемент в массиве), а затем используйте array_reverse () , чтобы перевернуть массив назад и просмотреть его. Или просто выполните обратный цикл for, где вы начинаете с конца и уменьшаете каждый цикл.

$file = file("test.txt");
$file = array_reverse($file);
foreach($file as $f){
    echo $f."<br />";
}
20
ответ дан 1 December 2019 в 17:16
поделиться

Чтение всего файла в массив и обратный ход - это нормально, если только файл не огромен.

Вы можете выполнить буферизованное чтение файла сзади наперед примерно так:

  • установите размер буфера_размер B - он должен быть длиннее самой длинной предполагаемой строки, иначе вам понадобится логика для увеличения размера буфера, если строки слишком длинные
  • set offset = длина файла - buffer_size
  • while the offset>=0
    • читаем байты размера буфера из смещения
    • читаем строку - она будет неполной, так как мы проскочили в середину строки, поэтому мы хотим убедиться, что следующий буфер, который мы читаем, заканчивается ею. Set offset = offset - buffer_size + длина строки
    • отбрасываем эту строку, читаем все следующие строки в массив и переворачиваем их
    • обрабатываем этот массив, чтобы сделать все, что вы хотели
2
ответ дан 1 December 2019 в 17:16
поделиться
Другие вопросы по тегам:

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