4

我正在尝试制作一个脚本来下载文件的一部分。只需用 CURL 和 fread 进行测试,我意识到流式处理过程中的 CURL 比 fread 慢。为什么?如何加快 curl 流式传输文件?我不喜欢使用 fread , fopen 因为我在流式传输过程中需要有限的时间。

这是我的示例代码。

$start = microtime(true);
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';

$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();

fread / fopen 仅需1.1s

$start = microtime(true);
$curl = curl_init('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg');
curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($curl, CURLOPT_RANGE, "0-2");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "3-5");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "6-8");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "9-11");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "12-14");
$response = curl_exec($curl);echo $response.'<br>';
curl_close($curl);

$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();

curl 大约需要 2.5 秒。如果我采取更多步骤来下载文件的更多部分。curl 会更慢。

为什么卷曲较慢?它是什么解决方案?

4

5 回答 5

3

它总是较慢,因为您添加了额外的 HTTP 调用往返。每个 curl_exec 都是一个 HTTP 请求。

于 2013-10-28T08:41:01.810 回答
2

您的问题是关于有许多部分请求或关于同一请求的增量缓冲读取。

fopen/fread 实现触发单个 HTTP 请求并多次读取它。

另一方面,curl 实现会触发许多 HTTP 请求,每个请求一个(请参阅部分范围请求)。所以我们在比较苹果和橙子

公平地说,fopen/fread 看起来像这样

$start = microtime(true);
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 3);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 6);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 9);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 12);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();

更新:我重写了我的答案

于 2013-10-28T09:13:25.847 回答
1

您可以使用curl_getinfo查看需要很长时间的内容。

缓慢可能是由于 curl 库的 DNS 查找。您是否尝试过使用 IP 地址而不是域作为请求 url?

编辑:或者,您可以设置CURLOPT_DNS_USE_GLOBAL_CACHEtrue并设置CURLOPT_DNS_CACHE_TIMEOUT为更长的值(例如 1 小时) - 默认情况下为 2 分钟。

源: http: //php.net/manual/en/function.curl-setopt.php

于 2013-10-23T09:33:33.800 回答
0

尝试Keep-Alive在 first 之前设置标题curl_exec,例如 300 秒,这样:

$headers = array("Keep-Alive: 300");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
于 2013-10-22T11:38:11.903 回答
0

您可以尝试以下解决方案:

curl_setopt($curl, CURLOPT_RANGE, "0-2, 3-5, 6-8, 9-11, 12-14");
$response = curl_exec($curl);echo $response.'<br>';
curl_close($curl);
$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();
于 2019-06-20T15:31:57.060 回答