php - 使用 php fgetcsv 读取巨大的 CSV 文件时遇到问题 - 了解内存消耗

标签 php out-of-memory fgetcsv

早上好, 实际上,我在尝试处理高达 4GB 的巨大 csv 文件时经历了一些惨痛的教训。

目标是通过给定的浏览节点以及某些给定的商品 ID (ASIN) 搜索 csv 文件(亚马逊数据源)中的某些商品。为了混合现有的元素(在我的数据库中)加上一些额外的新元素,因为有时元素会在市场上消失。我还过滤了项目的标题,因为有很多项目使用相同的标题。

我在这里阅读了很多 af 提示,最后决定使用 php 的 fgetcsv() 并认为该函数不会耗尽内存,因为它会逐行读取文件。 但无论我尝试什么,我总是内存不足。 我不明白为什么我的代码使用这么多内存。

我将内存限制设置为4096MB,时间限制为0。服务器有64 GB RAM和两个SSD硬盘。

有人可以检查一下我的代码并解释一下为什么我会耗尽内存,更重要的是如何使用内存?

private function performSearchByASINs()
{
    $found = 0;
    $needed = 0;
    $minimum = 84;
    if(is_array($this->searchASINs) && !empty($this->searchASINs))
    {
        $needed = count($this->searchASINs);
    }
    if($this->searchFeed == NULL || $this->searchFeed == '')
    {
        return false;
    }
    $csv = fopen($this->searchFeed, 'r');
    if($csv)
    {
        $l = 0;
        $title_array = array();
        while(($line = fgetcsv($csv, 0, ',', '"')) !== false)
        {
            $header = array();
            if(trim($line[6]) != '')
            {
                if($l == 0)
                {
                    $header = $line;
                }
                else
                {
                    $asin = $line[0];
                    $title = $this->prepTitleDesc($line[6]);
                    if(is_array($this->searchASINs) 
                    && !empty($this->searchASINs) 
                    && in_array($asin, $this->searchASINs)) //search for existing items to get them updated
                    {
                        $add = true;
                        if(in_array($title, $title_array))
                        {
                            $add = false; 
                        }
                        if($add === true)
                        {
                            $this->itemsByASIN[$asin] = new stdClass();
                            foreach($header as $k => $key)
                            {
                                if(isset($line[$k]))
                                {
                                    $this->itemsByASIN[$asin]->$key = trim(strip_tags($line[$k], '<br><br/><ul><li>'));
                                }
                            }
                            $title_array[] = $title;
                            $found++;
                        }
                    }
                    if(($line[20] == $this->bnid || $line[21] == $this->bnid) 
                    && count($this->itemsByKey) < $minimum 
                    && !isset($this->itemsByASIN[$asin])) // searching for new items
                    {
                        $add = true;
                        if(in_array($title, $title_array))
                        {
                           $add = false;
                        }
                        if($add === true)
                        {
                            $this->itemsByKey[$asin] = new stdClass();
                            foreach($header as $k => $key)
                            {
                                if(isset($line[$k]))
                                {
                                    $this->itemsByKey[$asin]->$key = trim(strip_tags($line[$k], '<br><br/><ul><li>'));                                
                                }
                            }
                            $title_array[] = $title;
                            $found++;
                        }
                    }
                }
                $l++;
                if($l > 200000 || $found == $minimum)
                {
                    break;
                }
            }
        }
        fclose($csv);
    }
}

最佳答案

我知道我的回答有点晚了,但我对 fgets() 和基于 fgets() 的东西(例如 SplFileObject->current() 函数)也有类似的问题。就我而言,它是在 Windows 系统上尝试读取 +800MB 文件时发生的。我认为 fgets() 不会释放循环中上一行的内存。因此,读取的每一行都保留在内存中,并导致致命的内存不足错误。我使用 fread($lineLength) 修复了它,但它有点棘手,因为您必须提供长度。

关于php - 使用 php fgetcsv 读取巨大的 CSV 文件时遇到问题 - 了解内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32622521/

相关文章:

php - 来自数据库的字母数字排序/排序

php - Selenium RC 通过 (winxp/winserver) 发送空白屏幕截图

c# - 在 C# 应用程序中使用多线程时出现 OutOfMemory 异常

python - C++在python中内存不足,剩余空间充足

php "continue"似乎不工作

memory - 单次调用 fgetcsv() 会耗尽 PHP 中的大内存限制

php - fatal error : Call to a member function prepare() - when using login function

php - 不使用 header 重定向从我的 PHP 将值发布到第三方支付网站

android - ViewPager 与 ImageView 给出 "java.lang.OutOfMemoryError: bitmap size exceeds VM budget"