2010-01-09 3 views
21

Возможно ли частично загрузить удаленный файл с помощью cURL? Скажем, фактический размер файла удаленного файла составляет 1000 КБ. Как загрузить только первые 500 КБ?Как частично загрузить удаленный файл с помощью cURL?

+0

Использование заголовков: https://unix.stackexchange.com/questions/121314/download-only-a-part-of-a-file –

ответ

34

Вы также можете установить параметр заголовка диапазона с PHP-завиток расширения в.

Но как отмечалось ранее, если сервер не соблюдает этот заголовок, но отправляет весь файл, он все равно загрузит. Например. http://www.php.net игнорирует заголовок. Но вы можете (дополнительно) установить обратный вызов функции записи и прервать запрос при получении большего количества данных, например.

// php 5.3+ only 
// use function writefn($ch, $chunk) { ... } for earlier versions 
$writefn = function($ch, $chunk) { 
    static $data=''; 
    static $limit = 500; // 500 bytes, it's only a test 

    $len = strlen($data) + strlen($chunk); 
    if ($len >= $limit) { 
    $data .= substr($chunk, 0, $limit-strlen($data)); 
    echo strlen($data) , ' ', $data; 
    return -1; 
    } 

    $data .= $chunk; 
    return strlen($chunk); 
}; 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, 'http://www.php.net/'); 
curl_setopt($ch, CURLOPT_RANGE, '0-500'); 
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $writefn); 
$result = curl_exec($ch); 
curl_close($ch); 
+0

+1 за хороший ответ. Это работает, потому что $ writefn() возвращает -1, когда предел достигнут. Когда функция обратного вызова возвращает что-либо, кроме количества байтов, переданных ему (в $ chunk), curl прерывает соединение. – GZipp

+0

Отлично. Когда я делал то же самое в Perl, мне пришлось использовать аварийный сигнал, который запускался и проверял размер файла, из-за отсутствия лучшего метода. Очень хаки, но это сработало. –

+0

Просто то, что мне нужно. Однако стоит упомянуть также CURLOPT_BUFFERSIZE, который определяет размер «куска». Поэтому, если ваш буфер очень большой, размер куска может легко содержать полную веб-страницу данных в любом случае (я думаю!) –

17

Получить первые 100 байт документа:

curl -r 0-99 http://www.get.this 

от ручного

убедитесь, что современный завиток

+3

Вы правильно, однако я обнаружил, что это не всегда надежен и зависит на сервере и не скручиваться. В случае с неверными делами завиток будет просто продолжать загрузку. –

+0

Я не могу скачать, когда я использую другой диапазон, например 100-200. Я получаю «завитушку» (18) ». Можно ли это решить? – akashrajkn

0

Это может быть ваше решение (скачать первый 500KB в output.txt)

curl -r 0-511999 http://www.yourwebsite.com > output.txt 
  • в то время как 511999 является 500^1024-1
0

Благодарим за хорошее решение VolkerK. Однако мне нужно было использовать этот код как функцию, поэтому вот что я придумал. Надеюсь, это полезно для других. Основное различие заключается в использовании ($ limit, & $ datadump), поэтому предел можно передать и использовать переменную $ datadump для ссылки, чтобы иметь возможность вернуть ее в результате. Я также добавил CURLOPT_USERAGENT, потому что некоторые веб-сайты не разрешают доступ без заголовка пользовательского агента.

Проверить http://php.net/manual/en/functions.anonymous.php

function curl_get_contents_partial($url, $limit) { 
    $writefn = function($ch, $chunk) use ($limit, &$datadump) { 
    static $data = ''; 

    $len = strlen($data) + strlen($chunk); 
    if ($len >= $limit) { 
     $data .= substr($chunk, 0, $limit - strlen($data)); 
     $datadump = $data; 
     return -1; 
    } 
    $data .= $chunk; 
    return strlen($chunk); 
    }; 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); 
    //curl_setopt($ch, CURLOPT_RANGE, '0-1000'); //not honored by many sites, maybe just remove it altogether. 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, $writefn); 
    $data = curl_exec($ch); 
    curl_close($ch); 
    return $datadump; 
} 

использование:
$ страница = curl_get_contents_partial ('http://some.webpage.com', 1000); // читаем первые 1000 байт
echo $ page // или делаем что-либо с результатом.

Смежные вопросы