簡體   English   中英

fread 的下載速度比 readfile 慢很多

[英]fread a lot slower for downloads than readfile

我正在通過 PHP 腳本從 URL 向我的用戶提供下載。 使用readfile()我獲得了連接可以支持的最大下載速度(大約 2.5MB/s),但是當我使用fopen, fread, fclose路由時,下載速度非常非常慢(大約 1-2KB/s)。

這是我的代碼:

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $filesize);
ob_clean();
flush();

$file = fopen($url, 'rb');

while(!feof($file)) {
    echo fread($file, 2014);
}

讀取文件代碼只是readfile($link); .

由於兩個原因,我不能只使用readfile()函數,一個是我想限制用戶的下載速度(我可以通過只讀取這么多數據來使用fread來做到這一點),而且我還想跟蹤用戶的下載速度正在下載(我可以用readfile()做到這一點,但它不計算部分下載)。

有誰知道為什么會發生這種情況或我該如何解決? 據我所知readfile()只是fopen, fread and fclose的包裝器fopen, fread and fclose所以我不明白出了什么問題。

編輯:為此最終使用了 cURL。

$curl = curl_init();
$options = array(
    CURLOPT_URL => $rdLink,
    CURLOPT_FAILONERROR => true,
    CURLOPT_BINARYTRANSFER => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_WRITEFUNCTION => 'readResponse'
);
curl_setopt_array($curl, $options);

if(!curl_exec($curl)) {
    header('Location: http://whatever.com');
    exit;
}
curl_close($curl);

function readResponse($ch, $data) {
    $length = mb_strlen($data, '8bit');

    echo $data;

    return $length;
}

使用stream_context_create()stream_get_contents()

$context = stream_context_create();
$file = fopen($url, 'rb', FALSE, $context);
while(!feof($file))
{
    //usleep(1000000);
    echo stream_get_contents($file, 2014);
}

您還可以嘗試使文件讀取長度更大並放入 usleep() 以減慢執行速度。 無論如何,對於最新版本的 PHP,流函數似乎比 fread 更推薦。 您可能還想在 fread() 或 stream_get_contents() 前面加上 @ 以抑制任何錯誤,至少在生產中是這樣。 沒有它,稍有不慎,您的文件就會損壞。

它可能在 PHP 或 Apache 中的某處進行緩沖(甚至可能是速率限制)。 嘗試改變:

while(!feof($file)) {
   echo fread($file, 2014);
}

到:

while(!feof($file)) {
   $s=fread($file, 2014);
   if($s===false)break;  //Crude
   echo $s;
   @ob_flush();@flush();
}

@前綴是因為他們可能會抱怨空緩沖區。)

正如freshwater先生所說,你應該對你的fread調用進行錯誤檢查,所以我在上面添加了一些基本的東西。

原因是 2014 年。操作系統比其他人更快地獲取 4096 字節數據部分。 但是如果你寫 2014,那么操作系統會嘗試從文件中讀取一個字節的數據來計算它。 這就是為什么需要這么長時間。 將 2014 更改為 4096

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM