>  기사  >  백엔드 개발  >  PHP로 대용량 파일을 읽는 여러 가지 방법

PHP로 대용량 파일을 읽는 여러 가지 방법

墨辰丷
墨辰丷원래의
2018-05-31 10:14:471391검색

이 글에서는 주로 PHP를 기반으로 대용량 파일을 읽는 여러 가지 방법을 소개합니다. 관심있는 친구들은 그것을 참고할 수 있습니다.

큰 파일을 읽는 것은 항상 골치 아픈 일이었습니다. PHP를 사용하여 작은 파일을 개발하고 읽는다면 이를 달성하기 위해 다양한 기능을 직접 사용할 수 있습니다. 그러나 큰 문서에 도달하면 일반적으로 사용되는 방법을 알게 될 것입니다. 정상적으로 사용할 수 없거나 시간이 너무 오래 걸립니다. PHP에서 대용량 파일을 읽는 문제에 대한 해결책을 살펴보겠습니다. 예제가 도움이 되기를 바랍니다.

시나리오: PHP는 1G 로그 파일과 같은 매우 큰 파일을 읽습니다. 저는 여기에서 400M access.log 파일을 사용하고 있습니다

1 직접 읽으려면 파일을 사용하세요

<?php
$starttime=microtime_float();
 
ini_set(&#39;memory_limit&#39;, &#39;-1&#39;);
$file = &#39;testfile.txt&#39;;
 
$data = file($file);
$line = $data[count($data) - 1000];
$endtime=microtime_float();
 
echo count($data),"<br/>";
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

실행 결과: 10127784줄 사용됨 총 7.8764359951s

내 컴퓨터에는 3G 메모리가 있습니다. 모든 파일을 메모리에 로드해야 하기 때문에 이 방법은 권장되지 않습니다. linux 명령 tail


<?php
 
$starttime=microtime_float();
 
$file = &#39;testfile.txt&#39;;
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 100 $file`;
 
echo $line,"<br/>";
 
$endtime=microtime_float();
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
 
//end

을 사용하세요. 쉽게 완료하는 데 몇 밀리초가 걸렸습니다. 이 방법은 Windows에서는 사용할 수 없습니다

3. fseek 기능을 사용하세요

이 방법은 파일의 모든 내용을 읽을 필요가 없습니다. 내용은 PHP가 C로 작성되었기 때문에 구현이 C에서 파일을 읽는 것과 비슷하고, 포인터의 이동을 통해 효율성이 상당히 효율적입니다. fseek를 사용하여 파일을 조작할 때 다양한 방법이 있으며 효율성이 약간 다를 수 있습니다.

다음은 일반적으로 사용되는 몇 가지 방법입니다


방법 1: fopen을 사용하여 파일 열기(파일 포인터 리소스 핸들에서)


<?php
$starttime=microtime_float();
 
$file = &#39;testfile.txt&#39;;
$fp = fopen($file, "r+");
 
$line = 100;
$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,"<br/>";
$endtime=microtime_float();
 
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

실행 결과: 0.338493108749

방법 2: 하나씩 읽기

<?php
$starttime=microtime_float();
 
$file = &#39;testfile.txt&#39;;
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;//4K的块
$fs = sprintf("%u", filesize($file));
$readData=&#39;&#39;;
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : $fs;
 
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) {
 
 $ns=substr_count($readData, "\n")-$num+2;
 preg_match(&#39;/(.*?\n){&#39;.$ns.&#39;}/&#39;,$readData,$match);
 $data = $match[1];
 break;
}
}
fclose($fp);
echo $data,"<br/>";
 
 
$endtime=microtime_float();
 
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

실행 시간: 0.00199198722839


한 줄씩 읽으려면 fgets 함수를 사용하세요

<?php
$file = fopen("testfile.txt","r");
 while(!feof($file))
 {
   echo fgets($file);
 }
 fclose($file);

spl 라이브러리 기능

<?php
try{
  foreach( new SplFileObject(&#39;testfile.txt&#39;) as $line)
  echo $line.&#39;<br />&#39;;
}catch (Exception $e){
  echo $e->getMessage();
}

또한 인터넷에는 블록 단위로 파일을 읽는 방법이 많이 있습니다. 관심 있는 독자는 시도해 볼 수 있지만 성공하지 못한 것 같습니다. .

위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부에 도움이 되었으면 좋겠습니다.


관련 권장 사항:

PHP의 TP5에서 요청 개체 메서드


PHP의 TP5 파일 업로드 메서드


php 2차원 연관 배열을 문자열로 변환하는 메서드

위 내용은 PHP로 대용량 파일을 읽는 여러 가지 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.