2012-06-19 25 views
-2

我是一名php程序员,目前我正在处理文件。我必须解析并将数据插入到mysql数据库。由于其大量的数据php无法加载或解析文件。即使我已将memory_limit增加到1500MB,我也会收到内存泄漏错误。使用php linux服务器解析大文件

FATAL: emalloc(): Unable to allocate 456185835 bytes 

我的文本文件包含文本和xml数据。我必须解析文本文件中的xml数据。

eg: <ajax>some text goes here</ajax> non relativ text <ajax>other content</ajax> 

在上面的例子中,我必须解析标签内的内容。如果任何人可以给出一些建议,以将每个标签分隔成单独的文件(例如:1.txt,2.txt),那么将会很棒(perl或c或shell脚本等)。

+0

你怎么做解析? – 2012-06-19 20:31:18

+0

你应该重新确定你的问题究竟需要什么。如果想按模式分割文件 - 问这个问题。如果你想要关于内存映射文件的建议 - 问这个问题。以上是有点混乱。 – jm666

+0

我正在使用file_get_contents并对整个数据进行preg_match。 – Ajaxmint

回答

1

咳嗽 ...一个1500 MB的内存限制是一个肯定的迹象,你已经离开了轨道。

你在哪里得到你的文件?我假设(给定大小)这是一个本地文件。如果您尝试使用file_get_contents()将文件加载到字符串中,值得注意的是文档是错误,并且该函数事实上并不使用内存映射I/O(参见bug 52802)。所以这不适合你。

您可能会尝试的是回落到更类似于C的(但仍然是PHP)构造,特别是fopen(),fseek()fread()。如果文件是带有换行符的已知结构,则可能还会考虑fgets()

这些应该让你在大块字节读入合理大小的缓冲区从中你可以做你的处理。由于看起来您正在处理标记字符串,因此您将不得不进行常规游戏,保持多个缓冲区,以便可以在其中累积数据直至可处理。这是相当标准的东西,涵盖了大多数介绍,例如,流处理C.

请注意,在PHP(或任何其他语言的事情),你也将不得不考虑字符串编码的问题,因为,一般来说,不再是1字节== 1字符(参考Unicode)。当你暗示,PHP可能不是这项任务的最佳语言(尽管它当然可以做到这一点)。但是你的问题并不是真正的语言特定问题。您遇到了处理没有内存映射的大文件的根本限制。

+0

谢谢你的回复。是的,我正在使用file_get_contents()。我会尝试使用fgets。 – Ajaxmint

0

实际上你可以在同一时间解析XML与PHP的一小块所以你不要实际上是在所有需要多大的内存:

set_time_limit(0); 
define('__BUFFER_SIZE__', 131072); 
define('__XML_FILE__', 'pf_1360591.xml'); 

function elementStart($p, $n, $a) { 
    //handle opening of elements 
} 

function elementEnd($p, $n) { 
    //handle closing of elements 
} 

function elementData($p, $d) { 
    //handle cdata in elements 
} 

$xml = xml_parser_create(); 

xml_parser_set_option($xml, XML_OPTION_TARGET_ENCODING, 'UTF-8'); 
xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); 
xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); 

xml_set_element_handler($xml, 'elementStart', 'elementEnd'); 
xml_set_character_data_handler($xml, 'elementData'); 

$f = fopen(__XML_FILE__, 'r'); 
if($f) { 
    while(!feof($f)) { 
    $content = fread($f, __BUFFER_SIZE__); 

    xml_parse($xml, $content, feof($f)); 

    unset($content); 
    } 
    fclose($f); 
} 
相关问题