Please enable java script to visit.
NOTEBOOK
HOMEPHP / MySQLJS / HTMLWXappPythonC++Blender其他
PHP 读取本地超大数据(txt/csv)的办法,包括顺序读取和逆序读取 - NOTEBOOK
PHP 读取本地超大数据(txt/csv)的办法,包括顺序读取和逆序读取
PHP / MySQL
Posted on 2023-10-08
摘要 : 将一整个大文件读取到内存中,会给服务器带来很大压力,会出现超时甚至宕机的情况。使用一行一行地读取数据,可以有效提高效率。
这里提供从文件开头开始读取内容的办法,也有从文件末端(尾部)开始读取文件的办法。
❱ 从头开始读取文件,可以抓取其中某些几行数据

// 从头开始读取文件,可以只读取某些行。//txt 输出 字符串, csv 输出 数组
// $start 默认 1 //$linesnum 读取多少行,默认空,即读取到文件结束。
// 原理是一行一行往后读,读取到需要的行,或者文件结尾就返回。
// function getFileContentByLine($filename, $filetype='txt',$start=null,$linesnum=null){
function get_lines_from_front($filename, $start=1,$linesnum=null){

$filetype = strtolower(end(explode('.',$filename))); // 获得小写后缀名
if($filetype!='txt' && $filetype!='csv'){ echo "Only txt or csv is acceptable."; return false;}
if(!$fp=fopen($filename,'rb')){echo "Fail to read file,Please recheck.";return false;}

if($start<=0){ $start = 1;} // 默认从第一行开始读取。
if($linesnum<0){ $linesnum = null;}
$n = 0;

while(!feof($fp)){
++$n;
if($filetype=='txt'){
// $out = fgets($fp, 4096); //4096 :设置一行最大字符。默认是1024
$out = fgets($fp); // 从 PHP 4.3 开始,忽略掉 length 将继续从流中读取数据直到行结束。
if($start <= $n){
$result .= $out; // txt 返回字符串
}
}elseif($filetype=='csv'){
$out = fgetcsv($fp); // fgetcsv($fp,0,',','"');
if($start <= $n && $out){ // 最后一行返回false时,不录入
$result[] = $out; // csv 返回数组
}
}
if($linesnum && $linesnum == $n-$start){break;}
}
fclose($fp);
return $result;
}


❱ 从尾部开始抓取数据

// 读取大文件最后$n行//顺序输出
// txt 输出 字符串, csv 输出 数组
// 原理,从后往前,使用 fseek 函数一个字符一个字符往前查询,查询到换行符,就开始读取一行输出。
function get_lines_from_back($filename,$n){
$filetype = strtolower(end(explode('.',$filename))); // 获得小写后缀名
if($filetype!='txt' && $filetype!='csv'){ echo "Only txt or csv is acceptable."; return false;}
if(!$fp=fopen($filename,'rb')){echo "Fail to read file,Please recheck.";return false;}

$pos=-2; // 设置为0时,如果最后一行只有换行符,去掉最后一饿换行符,返回完整n行数据。 设置为-2时,如果最后一行只有换行符,那返回n行数据+最后一个换行符。
$eof=""; // or ?? $eof=" ";
if($filetype=='txt'){
$result="";
}elseif($filetype=='csv'){
$result=array();
}
while($n>0){
while($eof!="\n"){ // 一直找到换行符停下,指针停下。
if(!fseek($fp,$pos,SEEK_END)){ // fseek 成功则返回 0;否则返回 -1
$eof=fgetc($fp); // 从文件指针中读取一个字符

$pos --;
}else{
$isEnd = true; // 表示第一次到达了文件头部
rewind($fp); // 这时指针在1,需要归为0,才能读取到文件第一行。
break; // 读取到最开始,无法再移动指针了。
}
}
if($filetype=='txt'){
// $result.=fgets($fp); //从指针的位置,读取一行,输出结果是逆序,最后一行在最前面
$result = fgets($fp).$result; // 从指针的位置,读取一行,输出结果是顺序,最后一行在最后面
}else{
$result[] =fgetcsv($fp); // csv 返回数组 //fgetcsv($fp,0,',','"');
}
$eof=""; // or ?? $eof=" ";
$n--;
if($isEnd){break;} // 达到了文件头部了,不再继续了。
}
fclose($fp);
if($filetype=='csv'){
$result = array_reverse($result);// 反转数组,不保留原来键名
}
return $result;
}