Как сохранить память при чтении файла в Php?

У меня есть файл 200 КБ, что я использую на нескольких страницах, но на каждой странице мне нужны только 1-2 строки того файла поэтому, как я могу только для чтения эти строки, в чем я нуждаюсь, если я знаю номер строки?

Например, если мне нужна только 10-я строка, я не хочу загружать в памяти все строки, просто 10-я строка.

Извините за мой плохой английский язык!

7
задан coolboycsaba 8 April 2010 в 22:13
поделиться

7 ответов

Если вы не знаете смещение линии, вам нужно будет прочитать каждую строку до этого момента. Вы можете просто выбросить старые строки (которые вам не нужны), просматривая файл в цикле с помощью чего-то вроде fgets () . (РЕДАКТИРОВАТЬ: вместо fgets () , я бы предложил решение @Gordon )

Возможно, лучшим решением было бы использование базы данных, поскольку движок базы данных будет выполнять тяжелую работу по хранению строк и позволит вам (очень эффективно) получить определенную «строку» (это будет не строка, а запись с числовым идентификатором, однако это то же самое ) без необходимости читать записи перед ним.

3
ответ дан 6 December 2019 в 07:05
поделиться
<?php
    $lines = array(1, 2, 10);

    $handle = @fopen("/tmp/inputfile.txt", "r");
    if ($handle) {
        $i = 0;
        while (!feof($handle)) { 
            $line = stream_get_line($handle, 1000000, "\n");

            if (in_array($i, $lines)) {
                echo $line;
                            $line = ''; // Don't forget to clean the buffer!
            }

            if ($i > end($lines)) {
                break;
            }

            $i++;
        } 
        fclose($handle);
    }
?>
1
ответ дан 6 December 2019 в 07:05
поделиться

Попробуйте SplFileObject

echo memory_get_usage(), PHP_EOL;        // 333200

$file = new SplFileObject('bible.txt');  // 996kb
$file->seek(5000);                       // jump to line 5000 (zero-based)
echo $file->current(), PHP_EOL;          // output current line 

echo memory_get_usage(), PHP_EOL;        // 342984 vs 3319864 when using file()

Для вывода текущей строки вы можете использовать current () или просто echo $ file . Я считаю более понятным использовать этот метод. Вы также можете использовать fgets () , но это получить следующую строку.

Конечно, вам нужны только средние три строки. Я добавил вызовы memory_get_usage , чтобы доказать, что этот подход почти не потребляет память.

19
ответ дан 6 December 2019 в 07:05
поделиться

Почему вы пытаетесь загрузить только первые десять строк ? Знаете ли вы, что загрузка всех этих строк на самом деле является проблемой?

Если вы не измеряли, значит, вы не знаете, что это проблема. Не тратьте свое время на оптимизацию без проблем. Скорее всего, любое изменение производительности, которое произойдет, если вы не загрузите весь файл 200 КБ, будет незаметным, если вы не знаете, что загрузка этого файла действительно является узким местом.

0
ответ дан 6 December 2019 в 07:05
поделиться

Меняется ли содержимое файла? Если он статичен или относительно статичен, вы можете составить список смещений, по которым вы хотите считывать данные. Например, если файл меняется раз в год, но вы читаете его сотни раз в день, то вы можете заранее вычислить смещения нужных вам строк и переходить к ним напрямую, например, так:

 $offsets = array();
 while ($line = fread($filehandle)) { .... find line 10 .... }
 $offsets[10] = ftell($filehandle); // store line 10's location
 .... find next line
 $offsets[20] = ftell($filehandle);

и так далее. После этого вы можете тривиально перейти к местоположению этой строки, например, так:

 $fh = fopen('file.txt', 'rb');
 fseek($fh, $offsets[20]); // jump to line 20

Но это может оказаться излишеством. Попробуйте провести бенчмаркинг операций - сравните, сколько времени занимает выполнение старомодного "прочитать 20 строк" по сравнению с предварительным вычислением/переходом.

2
ответ дан 6 December 2019 в 07:05
поделиться

Просто пропустите их без сохранения, например

$i = 1;
$file = fopen('file.txt', 'r');
while (!feof($file)) {
   $line = fgets($file); // this gets whole line from the file;
   if ($i == 10) {
       break; // break on tenth line
   } 
   $i ++;
}

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

0
ответ дан 6 December 2019 в 07:05
поделиться

используйте fgets () . 10 раз :-) в этом случае вы не сохраните все 10 строк в памяти

0
ответ дан 6 December 2019 в 07:05
поделиться
Другие вопросы по тегам:

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