如何逐行处理大型CSV文件?

4

我已成功编写了一个脚本,使用cURL下载CSV文件,然后将CSV解析为数组,代码如下:

$rows = array_map(function($a) {
    return str_getcsv($a, $delimiter);
}, explode("\n", $result));

然后我使用foreach迭代$rows,将某些内容保存到数据库中。脚本运行良好,但是当使用较大的CSV文件(>10,000行)时,脚本变得相当缓慢并出现了更多的错误。 我想把CSV文件分成几部分,这样不会将整个文件导入到一个变量中。我找到了以下解决方案,但仍然一次处理整个文件。是否有一种方法可以将CSV分成几部分并多次运行数据库函数?或者有没有更好的方法来处理这样的大型CSV文件? 我对处理大文件相对较新,请多多关照!

也许如果您展示一下您的代码,我们就能够提供更多帮助。 - RiggsFolly
2
使用您提供的解决方案逐行读取CSV文件,每隔x行将它们全部写入文件,清除内存并开始一个新文件。 - Soronbe
1个回答

7

将文件保存在某个位置,然后按照以下方式逐个文件块进行处理:

<?php
$filePath = 'big.csv';

//How many rows to process in each batch
$limit = 100;

$fileHandle = fopen($filePath, "r");
if ($fileHandle === FALSE)
{
    die('Error opening '.$filePath);
}

//Set up a variable to hold our current position in the file
$offset = 0;
while(!feof($fileHandle))
{
    //Go to where we were when we ended the last batch
    fseek($fileHandle, $offset);

    $i = 0;
    while (($currRow = fgetcsv($fileHandle)) !== FALSE)
    {
        $i++;

        //Do something with the current row
        print implode(', ', $currRow)."\n";

        //If we hit our limit or are at the end of the file
        if($i >= $limit)
        {
            //Update our current position in the file
            $offset = ftell($fileHandle);

            //Break out of the row processing loop
            break;
        }
    }
}

//Close the file
fclose($fileHandle);

如果限制大于行数,我们可以这样做:$chunkValOpt = [5000,1000, 500, 100, 10, 2, 1]; $chunk = 1; foreach ($chunkValOpt as $value){ $result = $this->chooseChunkSize( $value, $filePath ) ; if($result != 0){ $chunk = $value; break; } } //// chooseChunkSize( $value, $filePath ) - 几乎是相同的函数,它返回$tmp计数器,在第二个while中只包含:$i++;if($i >= $chunk)$tmp++; - Vit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接