首頁 >後端開發 >php教程 >如何在不耗盡記憶體的情況下處理3000萬個海量字串?

如何在不耗盡記憶體的情況下處理3000萬個海量字串?

Barbara Streisand
Barbara Streisand原創
2024-11-12 05:11:01744瀏覽

How to Process a Massive 30 Million Character String Without Running Out of Memory?

分析 3000 萬個海量字串

在處理大量資料時,遇到「記憶體不足」錯誤可能會令人困惑。考慮以下情境:您正在使用curl 檢索約3,050 萬個字元的CSV 檔案。嘗試使用常用方法(例如按 r 和 n 進行爆炸)將此資料分解為行數組會觸發可怕的記憶體分配錯誤。這就提出了一個問題:如何在有效操作大量資料的同時避免此類錯誤?

避免記憶體分配錯誤的策略

如先前的回覆中敏銳指出的:

  1. 避免將整個資料集儲存在記憶體中:嘗試將整個3000 萬個字串載入到記憶體中本質上是不切實際的。
  2. 利用 CURLOPT_FILE:另一種方法是使用curl的CURLOPT_FILE選項將資料直接定向到文件,從而無需在記憶體中進行中間儲存即可進行即時處理。

替代方法:使用自訂流包裝器

雖然CURLOPT_FILE 透過將資料寫入檔案有效解決了該問題,但某些情況下可能需要記憶體中處理。在這種情況下,實作自訂流包裝器提供了一個可行的解決方案。

  1. 流包裝器實作:定義一個定義stream_open()和stream_write()方法的流包裝器類別。
  2. 動態行擷取:在stream_write()中,利用explode("n")在資料區塊到達時將行與資料區塊隔離,為從先前區塊中繼承的不完整行維護一個緩衝區。
  3. 執行處理:對stream_write()中擷取的行進行必要的處理。這可能涉及驗證、過濾資料或將資料插入資料庫。

範例流包裝器:

class MyStream {
    protected $buffer;

    function stream_open($path, $mode, $options, &$opened_path) {
        return true;
    }

    public function stream_write($data) {
        $lines = explode("\n", $data);
        $lines[0] = $this->buffer . $lines[0];
        $this->buffer = $lines[count($lines)-1];
        unset($lines[count($lines)-1]);

        // Perform your processing here
        var_dump($lines);
        echo '<hr />';

        return strlen($data);
    }
}

註冊流包裝器:

stream_wrapper_register("test", "MyStream");

註冊流包裝器:

// Configure curl using CURLOPT_FILE
curl_setopt($ch, CURLOPT_FILE, fopen("test://MyTestVariableInMemory", "r+"));

// Execute curl to retrieve data from the source
curl_exec($ch);

// Close the stream
fclose($fp);
註冊流包裝器:

註冊流包裝器:註冊流包裝器:與Curl 結合:透過使用自訂流包裝器,您可以在可管理的區塊中處理大型資料集,而不會遇到記憶體分配錯誤。此方法允許在資料到達時對其進行處理,確保有效的記憶體利用。

以上是如何在不耗盡記憶體的情況下處理3000萬個海量字串?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn