当您计算大型集合并且不想同时为所有结果分配内存或不知道是否需要所有结果时,生成器非常有用,因为以处理结果的方式,通过仅为当前结果分配内存,可以将内存占用减少到最低限度。
所以这是一种非常快速的方式,消耗更少的内存来实现您的目标:
我们打开文件,读取精确数量的行,然后产生结果,同时保持下一次迭代的状态,从而使您能够非常快速地处理块并减少内存消耗。
这样做的好处是避免读取所有文件两次以构建块(读取一次以构建包含所有行的大数组,然后循环遍历该数组以构建块),然后最终允许您(第三time) 循环遍历块数组...
function file_get_x_lines($file,$amount=100){
if(!file_exists($file)||!is_file($file)||!is_readable($file))
return;
if(!is_int($amount)||$amount<1) $amount=1;
$handle=fopen($file,'rb');
$i=0;
while($line=fgets($handle)){
if($i===0)
$tmp=array();
$chunks[]=rtrim($line,PHP_EOL);
$i++;
if($i===$amount){
$i=0;
$tmp=$chunks;
$chunks=array();
yield $tmp;
}
}
if(!$line)
yield $chunks;
}
然后你可以像使用任何生成器一样使用它
foreach(file_get_x_lines(__FILE__) as $list) {
$list=json_encode($list);
//do stuff
}
如果你想保持与行号相同的键,你可以这样轻轻地改变函数:
function file_get_x_lines($file,$amount=100){
if(!file_exists($file)||!is_file($file)||!is_readable($file))
return;
if(!is_int($amount)||$amount<1) $amount=1;
$handle=fopen($file,'rb');
$i=0;
$j=1;
while($line=fgets($handle)){
if($i===0)
$tmp=array();
$chunks[$j]=rtrim($line,PHP_EOL);
$i++;
$j++;
if($i===$amount){
$i=0;
$tmp=$chunks;
$chunks=array();
yield $tmp;
}
}
if(!$line)
yield $chunks;
}