Bagaimana untuk membaca baris tertentu fail besar dalam php

藏色散人
Lepaskan: 2023-03-13 20:30:01
asal
2075 orang telah melayarinya

Cara melaksanakan PHP untuk membaca baris tertentu bagi fail besar: 1. Gunakan fungsi fail secara terus untuk beroperasi; 2. Panggil perintah ekor Linux untuk memaparkan beberapa baris terakhir; operasi fail; 4. , membaca melalui fungsi stream_get_line PHP.

Bagaimana untuk membaca baris tertentu fail besar dalam php

Persekitaran pengendalian artikel ini: sistem windows7, versi PHP7.1, komputer DELL G3

php Cara membaca tertentu baris fail besar ?

Pengenalan kepada pelbagai kaedah membaca fail besar dalam PHP

Membaca fail besar selalu menjadi pening kepala Kami boleh menggunakan pelbagai kaedah untuk membaca fail kecil menggunakan pelaksanaan Fungsi PHP. tetapi apabila anda sampai ke artikel besar, anda akan mendapati bahawa kaedah yang biasa digunakan tidak boleh digunakan secara normal atau mengambil masa terlalu lama dan terperangkap. Mari kita lihat penyelesaian kepada masalah membaca fail besar dalam PHP boleh membantu anda.

Dalam PHP, apabila membaca fail, cara terpantas ialah menggunakan beberapa fungsi seperti fail dan file_get_contents Beberapa baris kod ringkas boleh mencapai fungsi yang kita perlukan. Tetapi apabila fail yang dikendalikan adalah fail yang agak besar, fungsi ini mungkin tidak mencukupi Perkara berikut akan bermula dengan keperluan untuk menerangkan kaedah pengendalian yang biasa digunakan semasa membaca fail besar.

Keperluan:

Terdapat fail log 800M dengan kira-kira 5 juta baris Gunakan PHP untuk mengembalikan kandungan beberapa baris terakhir.

Kaedah pelaksanaan:

1 Gunakan terus fungsi fail untuk beroperasi

Memandangkan fungsi fail membaca semua kandungan ke dalam memori sekaligus, dan PHP untuk mengelakkan. beberapa menulis perbandingan Program buruk mengambil terlalu banyak memori dan menyebabkan memori sistem tidak mencukupi, menyebabkan pelayan ranap Oleh itu, secara lalai, penggunaan memori maksimum adalah terhad kepada 16M Ini ditetapkan melalui memory_limit = 16M dalam php.ini nilai Tetapkan kepada -1 untuk penggunaan memori tanpa had.

Berikut ialah sekeping kod yang menggunakan fail untuk mengekstrak baris terakhir fail ini:

<?php
  ini_set(&#39;memory_limit&#39;, &#39;-1&#39;);
  $file = &#39;access.log&#39;;
  $data = file($file);
  $line = $data[count($data) - 1];
  echo $line;
?>
Salin selepas log masuk

Pelaksanaan keseluruhan kod mengambil masa 116.9613 (s).

Mesin saya mempunyai memori 2G Apabila saya menekan F5 untuk menjalankan, sistem bertukar menjadi kelabu dan ia mengambil masa hampir 20 minit untuk memulihkannya. apakah akibatnya? Ini serius, jadi ia bukan pilihan terakhir. Perkara had memori tidak boleh dilaraskan terlalu tinggi.

2. Panggil terus perintah ekor Linux untuk memaparkan beberapa baris terakhir

Di bawah baris arahan Linux, anda boleh terus menggunakan akses tail -n 10.log untuk memaparkan beberapa baris terakhir dengan mudah daripada fail log, anda boleh terus menggunakan PHP untuk memanggil arahan ekor, dan melaksanakan kod PHP seperti berikut:

<?php
  $file = &#39;access.log&#39;;
  $file = escapeshellarg($file); // 对命令行参数进行安全转义
  $line = `tail -n 1 $file`;
  echo $line;
?>
Salin selepas log masuk

Keseluruhan pelaksanaan kod mengambil masa 0.0034 (s)

3 . Secara langsung menggunakan fseek PHP untuk memproses fail Operasi

Kaedah ini adalah kaedah yang paling biasa Ia tidak perlu membaca semua kandungan fail, tetapi beroperasi secara langsung melalui penunjuk, jadi kecekapannya agak cekap. Apabila menggunakan fseek untuk mengendalikan fail, terdapat banyak kaedah yang berbeza, dan kecekapan mungkin berbeza sedikit Berikut adalah dua kaedah yang biasa digunakan:

Kaedah 1

First pass fseek Cari EOF terakhir. fail, kemudian cari kedudukan permulaan baris terakhir, dapatkan data baris ini, kemudian cari kedudukan permulaan baris seterusnya, kemudian ambil kedudukan baris ini, dan seterusnya, sehingga baris $num ditemui .

Kod pelaksanaan adalah seperti berikut

<?php
$fp = fopen($file, "r");
$line = 10;
$pos = -2;
$t = " ";
$data = "";
while ($line > 0)
{
 while ($t != "\n")
 {
 fseek($fp, $pos, SEEK_END);
 $t = fgetc($fp);
 $pos--;
 }
 $t = " ";
 $data .= fgets($fp);
 $line--;
}
fclose($fp);
echo $data
?>
Salin selepas log masuk

Keseluruhan pelaksanaan kod mengambil masa 0.0095 (s)

Kaedah 2

Masih gunakan fseek untuk bermula dari hujung fail Mula membaca, tetapi kali ini ia bukan membaca sedikit demi sedikit, tetapi membaca sekeping demi sekeping Setiap kali sekeping data dibaca, data yang dibaca diletakkan dalam buf, dan kemudian aksara baris baharu (\. n) diluluskan nombor untuk menentukan sama ada baris $num terakhir data telah dibaca.

Kod pelaksanaan adalah seperti berikut

<?php
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
for ($len = 0; $len < $max; $len += $chunk)
{
 $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
 fseek($fp, ($len + $seekSize) * -1, SEEK_END);
 $readData = fread($fp, $seekSize) . $readData;
 if (substr_count($readData, "\n") >= $num + 1)
 {
 preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match);
 $data = $match[0];
 break;
 }
}
fclose($fp);
echo $data;
?>
Salin selepas log masuk

Seluruh pelaksanaan kod mengambil masa 0.0009(s).

Kaedah 3

<?php
function tail($fp, $n, $base = 5)
{
 assert($n > 0);
 $pos = $n + 1;
 $lines = array();
 while (count($lines) <= $n)
 {
 try
 {
  fseek($fp, -$pos, SEEK_END);
 }
 catch (Exception $e)
 {
  fseek(0);
  break;
 }
 $pos *= $base;
 while (!feof($fp))
 {
  array_unshift($lines, fgets($fp));
 }
 }
 return array_slice($lines, 0, $n);
}
var_dump(tail(fopen("access.log", "r+"), 10));
?>
Salin selepas log masuk

Seluruh pelaksanaan kod mengambil masa 0.0003(s)

Kaedah 4, fungsi stream_get_line PHP, bacaan pantas, 500,000 baris dibaca Untuk fail data besar, ia mungkin mengambil masa kira-kira 20 saat! Kod contoh adalah seperti berikut

$fp = fopen(&#39;./iis.log&#39;, &#39;r&#39;); //文件 
while (!feof($fp)) { 
 //for($j=1;$j<=1000;$j++) {     //读取下面的1000行并存储到数组中 
 $logarray[] = stream_get_line($fp, 65535, "\n"); 
    // break;
 // } 
  
 }
Salin selepas log masuk

Pembelajaran yang disyorkan: "Tutorial Video PHP"

Atas ialah kandungan terperinci Bagaimana untuk membaca baris tertentu fail besar dalam php. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
php
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan