我有下面的代码,它需要一个$filename
并在其中循环。如果第9列位于值数组中(此处未显示),则将其忽略。
否则,我将该行写到名称基于第三列的文件中。
if (($handle = fopen($filename, "r")) !== FALSE) {
fgetcsv($handle);
while (($line = fgetcsv($handle, 2000, ";")) !== FALSE) {
if (!in_array($line[8], $exclude)) {
$d = str_replace('/','',$line[2]);
$f = fopen($base.$d.'.csv', "a");
fputcsv($f, $line);
fclose($f);
unset($line);
}
}
fclose($handle);
}
这很好。但是,它非常慢。我有200Mb的CSV正在循环通过。
我的问题是它是否可以优化和/或我是否在做可悲的事情?
谢谢
打开和关闭文件总是很昂贵的操作,因此减少此操作将有助于您为输入文件中的每一行打开和关闭文件。
此代码使文件数组保持打开状态,并每次检查它是否已打开,如果已打开,则使用存储的句柄,如果未打开则存储新的句柄。然后在代码末尾,它循环遍历所有打开的文件并关闭所有文件...
if (($handle = fopen($filename, "r")) !== FALSE) {
$outHandles = [];
fgetcsv($handle);
while (($line = fgetcsv($handle, 2000, ";")) !== FALSE) {
if (!in_array($line[8], $exclude)) {
$d = str_replace('/','',$line[2]);
if ( isset($outHandles[$d]) ) {
$f = $outHandles[$d];
}
else {
$f = fopen($base.$d.'.csv', "a");
$outHandles[$d] = $f;
}
fputcsv($f, $line);
unset($line);
}
}
fclose($handle);
foreach ( $outHandles as $file ) {
fclose($file);
}
}