Sunucu Killing olmadan PHP ile Büyük Metin Dosyaları Ayrıştırma

3 Cevap php

Ben basit metin değiştirme (Aslında ben xml düzgün bir kaç düzenli durumlarda kaçmış değil) yapıyor (50M-200M arasında) bazı büyük metin dosyalarını okumak için çalışıyorum. Burada fonksiyon basitleştirilmiş bir versiyonu:

<?php
function cleanFile($file1, $file2) {
$input_file     = fopen($file1, "r");
$output_file    = fopen($file2, "w");
  while (!feof($input_file)) {
    $buffer = trim(fgets($input_file, 4096));
    if (substr($buffer,0, 6) == '<text>' AND substr($buffer,0, 15) != '<text><![CDATA[')
    {
      $buffer = str_replace('<text>', '<text><![CDATA[', $buffer);
      $buffer = str_replace('</text>', ']]></text>', $buffer);
    }
   fputs($output_file, $buffer . "\n");
  }
  fclose($input_file);
  fclose($output_file); 	
}
?>

Ne ben alamadım 150MB civarında, dosyaların büyük için PHP bellek kullanımı başarısız önce (2GB civarında) grafik kapalı gider. Ben bu büyük dosyaları okuma hakkında gitmek için en bellek verimli bir yol olduğunu düşündüm. Ben bu bellek için daha verimli olacaktır eksik bazı yöntem var mı? Belki de tahsil ediliyor gerektiği zaman bellekte şeyler saklıyor bazı ayar?

Diğer bir deyişle, bu çalışma değil ve ben bildiğim kadarıyla ben yanlış şeyler yapıyor değilim bildiğiniz gibi neden bilmek ve bilmiyorum. Bana gitmek için herhangi bir yön? Herhangi bir giriş için teşekkür ederiz.

3 Cevap

PHP gerçekten bunun için tasarlanmış değildir. Farklı bir işlem için iş yükünü ve onu aramak ya da PHP başlatabilirsiniz. I Python veya Perl kullanmanızı öneririz.

PHP'nin çöp toplama benim yetersiz anlayış, şu yardımcı olabilir:

  1. unset $buffer açıkça bunu temizlemek için GC söylüyorum, diske onu yazma zaman yapılır.
  2. Başka bir fonksiyonu if blok, yani GC çalışır bu işlev çıkar koydu.

Bu önerilerin ardındaki mantık her şeyin tek bir işlev içinde yapılır çünkü çöp toplayıcı belleği boşaltarak değil, ve GC çöp şüpheli olduğunu.

Bu birçok durumda başarısız bekliyoruz. 4096 bayt parçalarını okuyoruz. Kim cut-off <text> ortasında olmayacağını bilir? Hangi durumda str_replace işe yaramaz.

Eğer normal bir ifade kullanarak düşündünüz mü?