Не удается прочитать данные из CSV с 80 Тыс. записей

#php #csv #large-files #fgetcsv

#php #csv #большие файлы #fgetcsv

Вопрос:

Я пытаюсь прочитать CSV с более чем 80 Тыс. записей. К сожалению, я не в состоянии этого достичь. Может кто-нибудь, пожалуйста, помочь мне? Мой CSV-файл составляет около 100 МБ, и я увеличил memory_limit до 128 МБ.

Я увеличил memory_limit до 128 м. Я попытался использовать приведенный ниже код:

  $handle = fopen('products.csv');
  if ($handle !== FALSE) {
      $str ='';
      echo "IN";
      while (($data = fgetcsv($handle)) !== FALSE) {
        $str .= json_encode($data); // add each json string to a string variable, save later
        $array[]=$data;
      }
  }

  fclose($handle);
  $finalJsonString = json_encode($array);
  print_r($finalJsonString);
  

Output: null

Может кто-нибудь, пожалуйста, помочь мне, если у вас есть идея по этому поводу?

Спасибо

Комментарии:

1. для начала вы используете fgetcsv($handle) , но ваша переменная handle равна $h

2. @jibsteroos: Спасибо за ваш ответ. Извините, я забыл обновить код. Я обновил код. результат тот же.

3. что именно вам дает Output: null ? И какой цели это $str служит?

4. Попробуйте избавиться от $str переменной, которая продолжает увеличиваться с каждой прочитанной строкой. Если ваш входной файл составляет 100 МБ, эта строка в конечном итоге будет такого размера, а затем еще немного.

5. Вы собираетесь хранить здесь намного больше, чем 100MB. Сначала вы создаете $str синтаксис data JSON. Вы создаете $array то, что является просто данными. Вы создаете, $finalJsonString который является синтаксисом data JSON, и, наконец, вы повторяете $finalJsonString , который будет помещать синтаксис data JSON в системный выходной буфер. Это более 400 МБ прямо здесь.

Ответ №1:

Чтобы решить проблемы с использованием памяти при работе с большими файлами, вы могли бы использовать генератор.

Генератор позволяет использовать foreach для перебора набора данных без необходимости создавать массив в памяти, что может привести к превышению лимита памяти или потребовать значительного времени обработки для генерации (источник: php.net генераторы).

Это должно помочь вам на вашем пути:

 // the generator
function readCsv($csv)
{
    $handle = fopen($csv, "r");
    if ($handle) {
        while (!feof($handle)) {
            yield fgetcsv($handle);
        }
        fclose($handle);
    }
}

// initialize variables
$data = [];
$line = null;
$csv = "test.csv"; // change this to the csv-file you want to read
/* 
 * in the foreach do some logic
 * with the yielded csv content
 */
foreach(readCsv($csv) as $line) {
    // show for debug
    echo '<pre>';
    var_dump($line);
    echo '</pre>';
}

// show memory usage
echo "memory peak usage (Kb): " . memory_get_peak_usage()/1024;
  

Комментарии:

1. Вероятно, вам следует включить flush(); вызов в свой foreach, чтобы остановить слишком большой системный буфер вывода.

2. Да, хорошее предложение, я просто использовал var_dump() для целей отладки небольшого тестового файла. Я бы посоветовал OP не пытаться повторить 100MB содержимого csv…