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

PHP fread() 函數深度解析:大文件讀取、編碼識別與空字符陷阱完整指南

     編輯:PHP 綜合知識

函數原型與基本行為

string fread(resource $handle, int $length)

fread() 從文件指針讀取最多 $length 字節,遇到以下情況會停止:

  • 讀滿指定字節數
  • 到達 EOF
  • 網絡流有數據包可用時
  • 用戶空間流讀取達 8192 字節

基礎用法示例

$file = 'data.txt';
$fh = fopen($file, 'r');
$content = fread($fh, filesize($file));
fclose($fh);

三大核心注意事項

1. 大文件讀取導致內存溢出的解決方案

問題:filesize() 返回值超過 memory_limit 時,一次性 fread() 會報錯。

解決:分塊讀寫

set_time_limit(0); // 移除執行時間限制

$source = 'large_file.bin';
$dest = 'copy.bin';

$rfp = fopen($source, 'rb');
$wfp = fopen($dest, 'wb');

while (!feof($rfp)) {
    $chunk = fread($rfp, 1024 * 1024); // 每次 1MB
    fwrite($wfp, $chunk);
}

fclose($rfp);
fclose($wfp);
echo "大文件拷貝完成";

2. fread() 不識別文件編碼 —— 關鍵認知

PHP 7.0 及之前版本:fread() 純粹按字節讀取,完全不識別、不轉換編碼。

$handler = fopen('a.txt', 'rb'); // 二進制模式
$content = fread($handler, 1024);
echo $content; // 直接輸出字節流

顯示正常的前提:文件字節編碼 = PHP 腳本編碼 = HTML 頁面編碼 = 瀏覽器解碼編碼。任何一環不一致即產生亂碼。

現代解決方案:PHP 7.1+ 可用 mb_detect_encoding() 配合 mb_convert_encoding() 處理。

3. Windows 下文本模式讀取的「多一個空字符」陷阱

現象:

$size = filesize($file);
$handle = fopen($file, "rb"); // 二進制模式
while (!feof($handle)) {
    var_dump(fread($handle, $size)); // 最後會多輸出一次空字符串
}

原因:Windows 文本文件結尾有 EOF 標記(Ctrl+Z / 0x1A),二進制模式會讀到此字節。

解決方案:

  • 使用 fopen($file, 'r') 文本模式 + fgets() 按行讀取
  • 或判斷 feof() 前先檢查 fread() 返回值
// 推薦寫法
$handle = fopen($file, 'r');
while (($line = fgets($handle)) !== false) {
    // 處理每行
}
fclose($handle);

總結建議

場景推薦方式
小文件全讀file_get_contents()
大文件流式處理fopen() + fread(8192) 循環
文本文件按行處理fopen('r') + fgets()
二進制文件fopen('rb') + fread()
編碼不確定文件讀取後用 mb_detect_encoding() 檢測並轉碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved