-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 に答える