我在伺服器端(Apache環境)上放了一個安卓apk安裝包的下載連結,使用
readfile()
讀取apk檔案輸出下載後,手機安裝apk顯示解析包錯誤。但apk本身沒問題,下載後檔案的大小也是完整的。伺服器mime也設定了。後來換用
fread()
後輸出就好了。不明白是為什麼。搜尋了一下沒遇到解釋的很清楚的,有說是因為「對二進位友好」,有這麼一說嗎?
包括還有file_get_contents()
, fgets()
等另外的幾個檔案讀取函數和方法,一直都不能很好的分清什麼時候該用哪個。除了手冊之外,有沒有一些有應用情境的好的介紹文章?
補上前後的代碼:
readfile():
header("Content-type: application/vnd.android.package-archive"); header("Accept-Ranges: bytes");header("Accept-Length:".$filesize ); header("Content-Disposition: attachment; filename=".$name);readfile($file);
fread():
header("Content-type: application/vnd.android.package-archive"); header("Accept-Ranges: bytes");header("Accept-Length:".$filesize ); header("Content-Disposition: attachment; filename=".$name);$handle = fopen($file,"r"); echo fread($handle,$filesize);fclose($handle);
回複內容:
我在伺服器端(Apache環境)上放了一個安卓apk安裝包的下載連結,使用readfile()
讀取apk檔案輸出下載後,手機安裝apk顯示解析包錯誤。但apk本身沒問題,下載後檔案的大小也是完整的。伺服器mime也設定了。後來換用fread()
後輸出就好了。不明白是為什麼。搜尋了一下沒遇到解釋的很清楚的,有說是因為「對二進位友好」,有這麼一說嗎?
包括還有file_get_contents()
, fgets()
等另外的幾個檔案讀取函數和方法,一直都不能很好的分清什麼時候該用哪個。除了手冊之外,有沒有一些有應用情境的好的介紹文章?
補上前後的代碼:
readfile():
header("Content-type: application/vnd.android.package-archive"); header("Accept-Ranges: bytes");header("Accept-Length:".$filesize ); header("Content-Disposition: attachment; filename=".$name);readfile($file);
fread():
header("Content-type: application/vnd.android.package-archive"); header("Accept-Ranges: bytes");header("Accept-Length:".$filesize ); header("Content-Disposition: attachment; filename=".$name);$handle = fopen($file,"r"); echo fread($handle,$filesize);fclose($handle);
fread()
和 readfile()
fread()
最大一次效能讀取 8k長度的位元組數,所以不能一次性讀取大檔案去作下載。 優勢在於,操作更加靈活,每次讀取指定位元組的內容,用於下載時方便控制伺服器的流量。
readfile()
優勢是能夠一次性讀取大檔案;不需要PHP預讀到記憶體,下載速度更快,直接把檔案的處理交由伺服器。缺點就是不能控制負載。所以它是沒有記憶體限制的,如果遇到報記憶體錯誤,先調用 ob_end_flush()
之類的函數關閉緩衝區。
file_get_contents
也是沒 readfile()
快, 因為也是走了php的記憶體。但是在讀取小常值內容到字串變數時,這個函數最適合使用,簡單,更快。
fgets()
是一次讀取檔案中的一行了,再需要逐行處理檔案的時候,使用這個
如果是直接寫入或讀取全部直接用 file_get_contents() file_put_contents() 更方便
fread 可以讀取指定大小,讀取指定行等等,還能鎖定檔案功能比較強
以下是readfile手冊中的解釋:
readfile() 函數輸出一個檔案。
該函數讀入一個檔案並寫入到輸出緩衝。
若成功,則返回從檔案中讀入的位元組數若失敗,則返回 false,這個函數會在文檔最後輸出位元組數。