Как я могу загрузить несколько частей файла параллельно с библиотекой curl PHP? - PullRequest
3 голосов
/ 18 августа 2011

Я решил начать проект по ускорению загрузки с помощью curl в PHP, используя функции curl_multi.

Вот мой код:

set_time_limit(0);
error_reporting(E_ALL);
$fileurl = "http://hq-scenes.com/tv.exe";
$filename = basename($fileurl);
$size = getFileSize($fileurl);
$splits = range(0, $size, round($size/5));
$megaconnect = curl_multi_init();
$partnames = array();
for ($i = 0; $i < sizeof($splits); $i++) {
    $ch[$i] = curl_init();
    curl_setopt($ch[$i], CURLOPT_URL, $fileurl);
    curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 0); 
    curl_setopt($ch[$i], CURLOPT_FOLLOWLOCATION, 0); 
    curl_setopt($ch[$i], CURLOPT_VERBOSE, 1);
    curl_setopt($ch[$i], CURLOPT_BINARYTRANSFER, 1);
    curl_setopt($ch[$i], CURLOPT_FRESH_CONNECT, 0);
    curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT, 10);
    $partnames[$i] = $filename . $i;
    $bh[$i] = fopen(getcwd(). '/' . $partnames[$i], 'w+');
    curl_setopt($ch[$i], CURLOPT_FILE, $bh[$i]);
        $x = ($i == 0 ? 0 : $splits[$i]+1);
        $y = ($i == sizeof($splits)-1 ? $size : $splits[$i+1]);
        $range = $x.'-'.$y;
    curl_setopt($ch[$i], CURLOPT_RANGE, $range);
    curl_setopt($ch[$i], CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.29 Safari/535.1");
    curl_multi_add_handle($megaconnect, $ch[$i]); 
}

$active = null;

do {
    $mrc = curl_multi_exec($megaconnect, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($megaconnect) != -1) {
        do {
            $mrc = curl_multi_exec($megaconnect, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}
$final = fopen($filename, "w+");
for ($i = 0; $i < sizeof($splits); $i++) {
    $contents = fread($bh[$i], filesize($partnames[$i]));
    fclose($bh[$i]);
    fwrite($final, $contents);
}
fclose($final);

function getFileSize($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $h = fopen('header', "w+");
    curl_setopt($ch, CURLOPT_WRITEHEADER, $h);

    $data = curl_exec($ch);
    curl_close($ch);

    if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
        return $contentLength = (int)$matches[1];
    }
    else return false;
}

Все идет хорошо, кроме одного:

Последняя часть файла не достигает конца файла.фактический размер файла: 3279848 байт

диапазоны:

0-655970
655971-1311940
1311941-1967910
1967911-2623880
2623881-3279848

файлы детали с размером

tv.exe0 655360
tv.exe1 655360
tv.exe2 655360
tv.exe3 655360
tv.exe4 655360

Это делает конечный файл длиной 3276800 байт, но этодолжно быть 3279848 байт.И, конечно, исполняемый файл не работал: (

Обратите внимание, что файлы детали имеют одинаковый размер. Даже последний, который должен иметь еще несколько байтов. Так что проблема в диапазоне загрузки или что-то,не в процессе слияния.

Что я сделал не так?

Ответы [ 4 ]

3 голосов
/ 23 октября 2012

Я предлагаю вам добавить это после fclose($final);, чтобы удалить ненужные файлы!

foreach($partnames as $files_to_delete){ 
    unlink($files_to_delete); 
}
2 голосов
/ 18 августа 2011

Вы хотели бы использовать ceil() вместо раунда. Раунд может округлять ВНИЗ, что отрубит конец файла. CEIL округлит вверх, гарантируя, что указанные диапазоны охватывают весь файл:

$splits = range(0, $size, ceil($size/5));
                          ^^^^

например. Если размер файла равен 12, и вы делаете раунд (13/5), вы получите 2.

2 голосов
/ 18 августа 2011

Вы должны установить свои файловые указатели на 0 до фреда. чтение xy байтов с конца равно 0 байтов;)

$final = fopen($filename, "w+");
for ($i = 0; $i < sizeof($splits); $i++) {
  fseek($bh[$i], 0, SEEK_SET);
  $contents = fread($bh[$i], filesize($partnames[$i]));
  fclose($bh[$i]);
  fwrite($final, $contents);
}
2 голосов
/ 18 августа 2011

$size ничего не установлено.

После установки размера, который вы ожидали

655971 17 Aug 22:59 tv.exe0
655970 17 Aug 22:59 tv.exe1
655970 17 Aug 22:59 tv.exe2
655970 17 Aug 22:59 tv.exe3
655967 17 Aug 22:59 tv.exe4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...