首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 獲取檔案行數的兩種方法:stream_get_line 高效能 vs file() 簡便但耗記憶體

     編輯:PHP 綜合知識

統計大型文字檔 (如日誌、CSV、SQL dump) 行數是常見需求。本文對比兩種方法:stream_get_line() 逐行流式讀取 (常數記憶體) 與 count(file()) 一次性載入陣列 (記憶體隨檔案大小線性增長),分析效能差異、適用場景與邊界條件。

方法一:stream_get_line() — 高效能、低記憶體 (推薦大檔案)


關鍵優勢:

  • 常數記憶體:緩衝區固定 8KB,無論檔案多大 (GB 級) 記憶體佔用極低。
  • 可控緩衝:第二參數調整緩衝區大小,平衡系統呼叫次數與記憶體。
  • 自定義行尾:第三參數支援 "\n"、"\r\n"、"\r"、甚至自定義分隔符。

方法二:count(file()) — 簡潔但高記憶體風險


運作機制:file() 將整個檔案讀入記憶體,按行分割為陣列返回。count() 計算陣列元素數。

缺點:

  • 檔案 100MB → 記憶體佔用 100MB+ (陣列結構額外開銷)。
  • 超過 memory_limit (預設 128M) 會報錯中止。
  • 大檔案讀取慢、易觸發 OOM Killer。

效能對比實測參考 (100MB 檔案、100萬行)

指標stream_get_linecount(file())
峰值記憶體~2 MB~150 MB
執行時間~0.8 秒~1.2 秒
穩定性✅ 極佳❌ 易 OOM

其他替代方案速查

  • exec("wc -l $file"):Linux/macOS 最快,調用系統工具,需注意命令注入風險 (escapeshellarg) 與跨平台相容性。
  • fgets() 迴圈:while(fgets($fp)) $line++; 效能略遜於 stream_get_line (需掃描換行符)。
  • SplFileObject:$f = new SplFileObject($file); $f->seek(PHP_INT_MAX); echo $f->key() + 1; 物件導風格,內部同樣流式讀取。
  • 併行處理:超大檔 (GB+) 可用 pcntl_fork 分塊並行計數再合併。

選擇建議決策樹

檔案大小 < 10MB 且 memory_limit 充足 → count(file()) 最簡潔
檔案 10MB ~ 500MB          → stream_get_line() / SplFileObject
檔案 > 500MB 或嵌入式環境   → stream_get_line() (調大緩衝區) 或 wc -l
跨平台 CLI 工具             → 封裝 stream_get_line 為預設,Linux 可選 wc -l 優化

掌握流式讀取技巧,不僅解決行數統計,更是處理大型 CSV 匯入、日誌分析、資料清洗等串流處理任務的核心基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved