-2

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

    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 scripting..etc)。

4

2 回答 2

1

... 1500 MB 的内存限制是一个明确的迹象,你已经偏离了轨道。

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

您可能会尝试回退到更多类似 C(但仍然是 PHP)的结构,特别是fopen(),fseek()fread(). 如果文件是带有换行符的已知结构,您也可以考虑fgets().

这些应该允许您将块中的字节读入一个合理大小的缓冲区,您可以从中进行处理。由于看起来您正在处理标记的字符串,因此您将不得不玩通常的游戏,即保留多个缓冲区,您可以在其中积累数据直到可处理。这是大多数介绍中所涵盖的相当标准的内容,例如 C 中的流处理。

请注意,在 PHP(或任何其他语言)中,您还必须潜在地考虑字符串编码问题,因为通常情况下,1 字节 == 1 字符(参见 Unicode)不再是这种情况.

正如您所暗示的那样,PHP 很可能不是完成这项任务的最佳语言(尽管它确实可以做到)。但是您的问题实际上并不是特定于语言的问题。您遇到了在没有内存映射的情况下处理大文件的基本限制。

于 2012-06-19T20:36:51.753 回答
0

您实际上可以一次用 PHP 解析 XML 一个小块,因此您实际上根本不需要太多 ram:

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);
}
于 2013-02-27T23:10:32.727 回答