Как я открываю файл от строки X к строке Y в PHP?

Это (ab) использование оператора запятой, который берет список разделенных запятыми выражений, оценивает первое (ие) выражение (я), отбрасывает их, а затем все (...) разрешается до значения конечного выражения , Обычно это делается только при автоматической минимизации IMO, потому что синтаксис выглядит запутанным.

.reduce там

return titles.reduce((obj, title, index) => ((obj[title] = 
 values[index]), obj), {});

эквивалентно

return titles.reduce((obj, title, index) => {
  obj[title] = values[index];
  return obj;
}, {});

, что имеет гораздо больше смысла - он превращает массив названий (например, ['foo', 'bar']) и массив значений (например, ['fooVal', 'barVal']) и использует .reduce для преобразования их в один объект, { foo: 'fooVal', bar: 'barVal' }.

Первым аргументом обратного вызова .reduce является начальное значение аккумулятора (второй аргумент .reduce) или значение, которое было возвращено на последней итерации - приведенный выше код передает {} в качестве начального значения, назначает свойство объекту и возвращает объект на каждой итерации. .reduce - это обычно наиболее подходящий метод для превращения массива в объект, но если вы более знакомы с forEach, код эквивалентен

const obj = {};
titles.forEach((title, index) => {
  obj[title] = values[index];
});
return obj;
[ 1120] Хотя оператор запятой может быть полезен при игре в код, это, вероятно, не то, что следует использовать при попытке написать хороший читаемый код.

11
задан Xenph Yan 5 February 2009 в 05:41
поделиться

7 ответов

Вы не собирающийся мочь считать запуск со строки X, потому что строки могут иметь произвольную длину. Таким образом, необходимо будет читать из запуска, считая количество чтения строк для получения для выравнивания X. Например:

<?php
$f = fopen('sample.txt', 'r');
$lineNo = 0;
$startLine = 3;
$endLine = 6;
while ($line = fgets($f)) {
    $lineNo++;
    if ($lineNo >= $startLine) {
        echo $line;
    }
    if ($lineNo == $endLine) {
        break;
    }
}
fclose($f);
13
ответ дан 3 December 2019 в 00:49
поделиться

К сожалению, чтобы смочь читать из строки x к строке y, необходимо было бы смочь обнаружить разрывы строки..., и необходимо будет просканировать через целый файл. Однако принятие Вас не спрашивает об этом по причинам производительности, можно получить строки x кому: y со следующим:

$x = 10; //inclusive start line
$y = 20; //inclusive end line
$lines = file('myfile.txt');
$my_important_lines = array_slice($lines, $x, $y);

См.: array_slice

3
ответ дан 3 December 2019 в 00:49
поделиться

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

0
ответ дан 3 December 2019 в 00:49
поделиться

Да, вы можете сделать это легко с помощью SplFileObject::seek

$file = new SplFileObject('filename.txt');
$file->seek(1000);
for($i = 0; !$file->eof() && $i < 1000; $i++) {
    echo $file->current(); 
    $file->next();
}

Это метод из интерфейса SeekableIterator, не путать с fseek.

А поскольку SplFileObject является итерируемым, вы можете сделать это еще проще с помощью LimitIterator:

$file = new SplFileObject('longFile.txt');
$fileIterator = new LimitIterator($file, 1000, 2000);
foreach($fileIterator as $line) {
    echo $line, PHP_EOL;
}

Опять же, это нулевой метод, так что это строки с 1001 по 2001.

35
ответ дан 3 December 2019 в 00:49
поделиться

Вот возможное решение:)

<?php
$f = fopen('sample.txt', 'r');
$lineNo = 0;
$startLine = 3;
$endLine = 6;
while ($line = fgets($f)) {
    $lineNo++;
    if ($lineNo >= $startLine) {
        echo $line;
    }
    if ($lineNo == $endLine) {
        break;
    }
}
fclose($f);
?>
3
ответ дан 3 December 2019 в 00:49
поделиться

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

Я думаю, что это невозможно без какого-то кэша или перебора строк одна за другой.

3
ответ дан 3 December 2019 в 00:49
поделиться

Я боялся этого... Думаю, это план Б :S

Для каждого AJAX запроса я собираюсь:

  1. Считать в строку количество строк, которые я собираюсь вернуть клиенту.
  2. Копировать остаток файла во временный файл.
  3. Возвращаем строку клиенту.

Это убого, и это, вероятно, будет довольно медленно с файлами в 10,000+ строк, но я думаю, это лучше, чем читать одно и то же снова и снова, по крайней мере, временный файл становится короче с каждым запросом... Нет?

0
ответ дан 3 December 2019 в 00:49
поделиться
Другие вопросы по тегам:

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