PHP,将一个大文件分割成包含字符串搜索的部分


PHP, Splitting a Large File into parts incorporating a String search

我有一个超过400Mb的文件

这是一个只以这种方式分发的时刻表数据库。

在这个文本文件中有一个字符串,它标志着数据记录的开始。

这个字符串总是以"BSN"开头,同样地,也有一个字符串标记数据记录的结束,总是以"LT"开头

我想了解的是如何将数据文件切成块,包含1000数据记录。然后,当这个循环完成后,我可以依次导入这些文件。

创建的文件必须在新文件夹中按顺序编号…

[edit]记录集长度差异很大[/edit]

下面是其中一个组的示例:

BSNC031551112111206240000001   << DATA RECORD START >> 
BX         EMYEM129000                                                           
LOSHEFFLD 2235 2235                                                
LIDORESNJ                                              
LISPDN                                       
LTDRBY    2326 23266           << DATA RECORD END >>                                        
BSNC033501112111205130000001   << NEXT RECORD >>
BX         EMYEM118600    

* & lt; & lt;

添加>>标签是为了便于理解,它们在文件中不存在。

我目前使用PHP的fopen/fgets方法在这里读取文件

像这样的东西应该为您工作

$fp = fopen($bigfile, "r");
$file_num = 1;
$prefix = "FILE_";
$suffix = ".DAT";
$buff = "";
$recNo = 0;
while ($rec = fgets($fp)){
    if (substr($rec, 0,3) == 'BSN'){
        $recNo++;
    }
    if ($recNo == 1000){
        // reset record counter
        $recNo = 1;
        // flush out the file
        file_put_contents($prefix.$file_num.$suffix, $buff);
        // clear the buffer
        $buff = "";
        // increment the file counter
        $file_num++;
    }
    // add to the buffer
    $buff.= $rec;
}
fclose($fp);
// flush the remainder
if ($buff) file_put_contents($prefix.$file_num.$suffix, $buff);

如果您有预定义的数据结构,您可以使用分割命令(unix):

 split -l 6000 your_big_file.txt data_

该命令将大文件分成6000个小文件(1000条数据记录)。

或者如果数据结构不统一,可以使用perl one - liner:

perl -n -e '/^BSNC/ and open FH, ">output_".$n++; print FH;' your_big_file

Perl可以逐行解析大文件,而不是将整个文件放到内存中。

将为每个数据记录创建新文件。不要担心Ext4文件系统每个目录有40亿个文件的理论限制。

在此之后,可以使用PHP脚本将所有数据导入数据库。