处理大文件时最大限度地减少内存使用量
如果我们需要解析一个大文件,例如一个包含数百万行的超过 10 MB 的 CSV 文件,有些人会使用 file
或 file_get_contents
函数,最后点击 memory_limit
设置
允许的内存大小为 XXXXX 字节耗尽
错误。考虑以下来源(top-1m.csv 正好有 100 万行,大小约为 22 MB)
var_dump(memory_get_usage(true));
$arr = file('top-1m.csv');
var_dump(memory_get_usage(true));
这输出:
int(262144)
int(210501632)
因为解释器需要保存 $arr
数组中的所有行,所以它消耗了大约 200 MB 的 RAM。请注意,我们甚至没有对数组的内容做任何事情。
现在考虑以下代码:
var_dump(memory_get_usage(true));
$index = 1;
if (($handle = fopen("top-1m.csv", "r")) !== FALSE) {
while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL, FILE_APPEND);
$index++;
}
fclose($handle);
}
var_dump(memory_get_usage(true));
哪个输出
int(262144)
int(262144)
所以我们不使用单个额外的内存字节,而是解析整个 CSV 并将其保存到另一个文件中,以反转第二列的值。那是因为 fgetcsv
只读取一行,而 $row
在每个循环中被覆盖。