如何在不超时的情况下解析大型CSV文件


How to parse Large CSV file without timing out?

我正在尝试解析一个50兆字节的.csv文件。文件本身很好,但我正在努力克服所涉及的大量超时问题。每个都设置为上传方式,我可以轻松上传并重新打开文件,但在浏览器超时后,我收到500内部错误。

我的猜测是,我可以将文件保存到服务器上,打开它,并保留我处理的行的会话值。在某一行之后,我通过刷新重置连接,并在我停止的那一行打开文件。这是一个可行的想法吗?以前的开发人员制作了一个效率非常低的MySQL类,它控制着整个网站,所以如果不必要的话,我不想写自己的类,我也不想破坏他的类。

TL;DR版本:保存CSV文件中我当前所在的最后一行是否有效,该文件包含38K行产品,然后在X行之后,重置连接并从我停止的位置开始?或者有没有其他方法可以在不超时的情况下解析大型CSV文件?

注意:这是PHP脚本执行时间。目前,在38K线路上,通过命令行运行大约需要46分5秒。当我从浏览器中删除它时,它100%都能正常工作,这表明它是浏览器超时。正如谷歌告诉我的那样,Chrome的超时是不可编辑的,Firefox的超时也很少起作用。

您可以这样做:

<?php
namespace database;
class importcsv
{
    private $crud;
    public function __construct($dbh, $table)
    {
        $this->crud = new 'database'crud($dbh, $table);
        return $this;
    }
    public function import($columnNames, $csv, $seperator)
    {
        $lines = explode("'n", $csv);
        foreach($lines as $line)
        {
            'set_time_limit(30);
            $line = explode($seperator, $line);
            $data = new 'stdClass();
            foreach($line as $i => $item) 
            {
                if(isset($columnNames[$i])&&!empty($columnNames[$i]))
                    $data->$columnNames[$i] = $item;
            }
            @$x++;
            $this->crud->create($data);
        }
        return $x;
    }
    public function importFile($columnNames, $csvPath, $seperator)
    {
        if(file_exists($csvPath))
        {
            $content = file_get_contents($csvPath);
            return $this->import($columnNames, $content, $seperator);
        }
        else
        {
            // Error
        }
    }
}

TL;DR:'set_time_limit(30);每次你通过一条线路循环可能会解决你的超时问题。

我建议从命令行运行php,并将其设置为cron作业。这样你就不必修改你的代码。不会出现超时问题,您可以轻松解析大型CSV文件。

也检查此链接

由于拼写错误和语法问题,您的帖子有点不清楚,请您编辑一下好吗?

如果您说Upload本身还可以,但延迟是在处理文件时,那么最简单的方法就是使用多个线程并行解析文件。您可以使用java内置的Executor类,或者Quartz或Jetlang来实现这一点。

  • 查找文件的大小或行数
  • 选择线程负载(例如每个线程1000行)
  • 启动执行程序
  • 循环读取文件
  • 对于ach 1000行,创建一个Runnable并将其加载到Executor
  • 启动执行程序
  • 等待所有线程完成

每个可运行程序都这样做:

  1. 获取连接
  2. 插入1000行
  3. 记录结果
  4. 关闭连接