【发布时间】:2013-05-16 09:03:14
【问题描述】:
我正在尝试将一个大文件从外部 API 传递给用户,(考虑 100MB 或更多)
目前,我正在使用一些偏执的脚本(由于过去的故障)来尽快下载脚本。
“下载”仅指浏览器上的下载触发器,而不是文件的实际下载。只是用户可以选择他想要保存文件的位置。
set_time_limit(0);
apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 0);
ini_set('output_buffering', 0);
ini_set('implicit_flush', 1);
for($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
ob_implicit_flush(1);
header('Content-Description: File Transfer');
header('Content-type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Cache-Control: private');
ob_flush();
flush();
$fh = fopen($external_api_url, 'rb');
while(!feof($fh))
{
echo fread($fh, 512);
ob_flush();
flush();
}
fclose($fh);
使用此脚本,50mb 的文件仍然需要 20 秒才能显示下载弹出窗口,而更大的文件则需要更长的时间。
有什么方法可以更快地开始直播吗?
编辑: 我也尝试过 fpassthru() 和 readfile() 但对于同一个 50mb 文件需要 40 秒,这让我觉得这种方式更好。我也玩过不同的读取大小(512、256、64,还有其他几个),但我没有注意到差异)
【问题讨论】:
-
如果您有 PHP 5,您是否尝试过
$contents = stream_get_contents($fh); echo $contents;或file_get_contents(...)而不是您的while循环?此外,fread() 实际上鼓励您一次读取 8192 个字节,因为那是块大小。 -
@Arthur 在将整个文件发送给用户之前,stream_get_contents 和 file_get_contents 不会等待在 PHP 中下载整个文件吗?此外,我不知道 8192 bute 块的大小,这可以解释为什么我尝试的不同值(都在这个数字之下)给出了相同的结果。有没有办法降低块大小?