2012-08-03 46 views
1

我试图解析一个50兆字节.csv文件。该文件本身很好,但我试图超过涉及的大量超时问题。每个设置上传明智,我可以轻松地上传和重新打开该文件,但浏览器超时后,我收到500内部错误。如何在不超时的情况下解析大型CSV文件?

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

TL; DR版本号:那么当我保存当前存在38K行产品的CSV文件的最后一行时,并且在X行数后重置连接并从哪里开始我离开了?或者还有另一种解决大型CSV文件没有超时的方式?

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

+0

你应该详细说明什么是超时。您与MySQL的连接,PHP脚本执行时间还是其他?你有没有考虑过设置超时时间? – JYelton 2012-08-03 17:01:21

+0

您应该考虑让脚本先分割文件。 – 2012-08-03 17:09:15

+0

@JYelton I这是PHP脚本执行时间。目前在38K行,通过命令行运行大约需要46分钟和5秒钟。当我从浏览器中删除它时,它100%正常工作,表明它是浏览器超时。就谷歌告诉我的,Chrome的超时时间不可编辑,Firefox的超时工作很少。 – lxndr 2012-08-03 17:13:21

回答

1

我建议从命令行运行PHP,并将其设置为cron作业,这样你不必修改你的代码,不会有超时问题,您可以轻松地分析大量的CSV文件

还要检查这link

+0

我希望我可以做这个选择,但它必须在网页上运行,并且必须由完全不知道网站如何工作的人完成。我不能给他们命令行访问权限,并要求他们每周运行一次,因为他们会告诉我不,并添加一些其他丰富多彩的词语拒绝。 – lxndr 2012-08-03 17:22:29

+0

我改变了我接受的答案。这正是我所做的。我将这个软件包发送到服务器,并将其作为cron作业运行。运行12小时后顺利运行。这50MB的文件变成了256MB的文件,每次需要花费1小时才能解析。谢谢你的帮助。 – lxndr 2013-01-17 21:30:41

+0

你的链接给404 http://www.webpronews.com/php-cli-and-cron-2004-04 – 2016-09-19 05:09:39

1

由于错别字和语法,你的帖子有点不清楚,你能编辑吗?

如果您在说上传本身没问题,但延迟处理文件,那么最简单的方法就是使用多线程并行解析文件。您可以使用java内置的Executor类,或Quartz或Jetlang来执行此操作。

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

每个运行的做到这一点:

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

你可以做这样的事情:

<?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);每次THROU行可能会解决您的超时问题。

+0

这是一段体面的代码,如果不是因为我的产品有许多不同的事情需要发生,而不是仅仅进行插入,那么它就会起作用。谢谢,我可能会采取这些代码并将其用于其他想法。 – lxndr 2012-08-03 18:00:42

相关问题