2012-08-10 138 views
0

我正在做一个CSV上传,其中有35,000行内容正在进行,我试图想到一种方法来开始解析CSV文件的行“X ”。我一直刷新页面并保存每次最后一行,以便修复浏览器遇到的超时问题。现在,我只需要知道如何在我离开的那条线上启动我的CSV文件。在线解析CSV文件“X”

while(($data = fgetcsv($handle, 0, ",")) !== false) { 
    if($i > 2000) { break; } 
    //start parsing here 
    $i++ 
} 
$_SESSION['lastLine'] = $i; 
$_SESSION['filepath'] = $filepath; 
//resend headers 

我将文件路径保存为会话,因为它已上传到临时文件夹,我可以重新访问它。所以我第一次上传时,我完全满意地欣赏了所有2000线。标题重置并重新启动该过程,但由于$ _SESSION ['lastline']现在是2001年,代码中断(这很好)。我需要弄清楚的是,我怎样才能开始我在2001年的解析并在4000年再次破解。这将持续到所有35,000行完成。

我在想设置break语句解析前,说:

if($i < $_SESSION['lastLine']) { $i++; } 
if($i > $_SESSION['lastLine'] + 2000) { break; } 

我的问题是,这样做35000线CSV意味着最后的10个左右的运行,将不得不做的我++循环数千甚至在分析甚至开始之前。我四处寻找一些方法来在“X”行开始CSV文件,这将是我的首选方法,但我找不到任何东西。任何帮助都是极好的。

+0

只是设置为会话不仅最后一行索引,但缓冲区大小(2000),并在循环中使用它作为行的最大值 – tijs 2012-08-10 14:48:38

回答

1

使用ftell()来保存您在文件中的位置。然后,在重新启动fgetcsv()循环之前,您可以将fseek()移动到该位置,例如

while($row = fgetcsv($handle)) { 
    $cur_pos = ftell($handle); 
    if ($some_condition) { 
      break; 
    } 
} 
..... 

fseek($handle, $cur_pos); // jump back to last position 
... continue on wards ... 
+0

标记您的答案是最好的几个,但不幸的是我用我的选择(它的工作),因为我需要一个半小时内快速修补的问题。非常感谢您的回复,当我有第二次回到这个客户时,我会用你的想法,因为我确信它比我的效率高10倍。 – lxndr 2012-08-10 15:09:42

+0

对于其他我读过这个有用的解决方案的人: 1)函数是fgetcsv(不是fetgetcsv,如第一行所示) 2)PHP手册警告:“某些文件系统函数可能会返回大于2GB的文件的意外结果“见http://php.net/manual/en/function.ftell.php – globalSchmidt 2014-08-24 21:38:48

+0

我认为它是[fgetcsv](http://php.net/manual/en/function.fgetcsv.php)而不是'fetgetcsv '。 – 2015-12-05 16:37:26

0

您应该保存字节随着行号偏移,则fseek到字节开始解析前偏移。

0

正如我发现FSEEK被抵消,而不是线 字符,我使用SplFileObject

像这样

$file = new SplFileObject('your-csv-file.csv'); 
//this is zero based so need to subtract 1 
$file->seek(2); /// Going to line 3 
$arr=$file->fgetcsv(); 
print_r($arr); 

若要从行号

while(!$file->eof()) 
{ 
    $row=$file->fgetcsv(); 
    print_r($row); 
} 

函数迭代整个CSV链接: - seekfgetcsv