繁体   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