splFIleObject 处理大文件

我有一个10w 左右的数据 全是json,没行一个json 字符串。

我想循环批量去处理怎么办?

测试发现php处理这样的一个80M大文件,全部读出来反序列化一下就要900M内存。

没办法,只能去读每行处理。

问题一:我怎么知道一个大文件有多少行?

读取完 count 慢占内存高:

搜了一个:

$f = fopen ($filename, "r");
$line = 0;
while (stream_get_line($f, 20480, PHP_EOL)) {
  $line++;
}
fclose($f);

问题二:如何读取大文件里的指定X行到Y行?

$file = new \SplFileObject($filename);
$row = 10;
$arr = [];
$start_line = $row * ($page-1);
if($start_line > $max){
  return '导入结束,共花时间'. time()-$begin.'s';
}
$file->seek($start_line);
for ($i = $start_line; $i < $row + $start_line; $i++) {
  $line = $file->current();
  $json = json_decode($line, true);
  if(false !== $json){
    if(is_array($json['result'])){
      foreach ($json['result'] as $key => $value) {
        $arr[$value['title']][] = $value['pics'];
      }
    }
    unset($json);
    unset($line);
  }
  $file->next();
}

上面的是模拟分页式的每次读10行,$start_line 和 $start_line+ $row 其实就对应 X 和Y。

后来SAE上相搞大文件的,但是sae 提交不上去,sae svn 文件对文件大小有限制,就分割吧:

split -l 100 ./good_album.json good_album.json_

后面,最后一个参数一定要带上,那个是分割后的前缀,不然是 aa ab 这种没规律文件,我们怎么遍历?

读取目录下某个前缀的文件名列表:

$list = array_map('basename', glob('./public/'.'good_album.json_*'));

标签:none