Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многопоточность + разбитие, скачивание файла 
V
    Опции темы
slva2000
Дата 5.12.2010, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 29.10.2005

Репутация: нет
Всего: нет



Доброго дня.

Задача: скачать файл  с удалённого сервера, разбив его на несколько частей, и добавив каждую часть в мультипоточное скачивание.

Пытался использовать отличный класс MultiCurl но не удалось реализовать до конца - не нашлось опции для ограничения "верхней" планки (т.е. позиции, до которой скачивать очередную часть файла), в то же время есть опция CURLOPT_RESUME_FROM, позволяющая получать контент с указанной позиции, в байтах.

С позициями всё как бы ясно, например так:

Код

$fh = fopen($url, "r");
while (!feof($fh)) {
    $line = fread($fh, 4000);
    file_put_contents("file.txt".$fn, $line, FILE_APPEND);
}
fclose($fh);


но вот с многопоточностью пока не додумал. Может есть готовые решения?

Спасибо.

Это сообщение отредактировал(а) slva2000 - 5.12.2010, 13:17
PM MAIL   Вверх
umka
Дата 5.12.2010, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 23.1.2004

Репутация: нет
Всего: 0



Думаю, нужно сначала "разметить" файл на несколько кусков (у каждого куска есть стартовая позиция и длина), а потом уже после fork-а, каждый child скачает свой кусочек и запишет его в нужное место сохраняемого файла.
PM MAIL WWW   Вверх
slva2000
Дата 5.12.2010, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 29.10.2005

Репутация: нет
Всего: нет



Код

$url = "http://site.ru/1.txt";
$n=5; //сколько частей
$file_size = remote_filesize($url); //функция на curl определния размера удалённого файла
$lengh = floor($file_size/$n);

for($i=0; $i<$file_size; $i=$i+$lengh)
{
    if (($i+$lengh) <= $file_size)
        $from_to[$i] = $i+$lengh;
    else
        $from_to[$i] = $file_size;
    $i++;
}


Вот набрасал... В результате получается именнованный массив, в котором:
имя ключа - с какой позиции забирать данные
значение ключа - до какой позиции забирать данные
PM MAIL   Вверх
slva2000
Дата 5.12.2010, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 29.10.2005

Репутация: нет
Всего: нет



Дописал полностью код с использовапнием Curl (ссылка на класс в первом посте):

Код


<?

$url_s = "http://site.ru/1.txt";
$n=10; //колличество частей разбития одного файла

$file_size = remote_filesize($url_s);
$lengh = floor($file_size/$n);
for($i=0; $i<$file_size; $i=$i+$lengh)
{
    if (($i+$lengh) <= $file_size)
        $from_to[$i] = $i+$lengh;
    else
        $from_to[$i] = $file_size;
    $i++;
}



include_once 'MultiCurl.class.php'; // подключение класса
@set_time_limit(0);


$file_size = remote_filesize($url_s);


class MyMultiCurl extends MultiCurl {
    protected function onLoad($url, $content, $info, $parts) {
        file_put_contents($parts.".tmp",$content);
    }
}

try {
    $mc = new MyMultiCurl();
    $mc->setMaxSessions(10); // кол-во потоков для ряда файлов.
    $mc->setMaxSize(50000000); //максимальный размер одного файла, Байт
   
    foreach($from_to as $from => $to)
    {
        $range = $from."-".$to;
        $mc->addUrl($url_s, array(CURLOPT_RANGE => $range));
    }

    $mc->wait();
} catch (Exception $e) {
    die($e->getMessage());
}

$file_array = glob("*.tmp");
foreach($file_array as $item)
{
    file_put_contents("file.txt", file_get_contents($item), FILE_APPEND);
}




######################

function remote_filesize($uri,$user='',$pw='')
{
    ob_start();
    $ch = curl_init($uri);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    if (!empty($user) && !empty($pw))
    {
        $headers = array('Authorization: Basic ' .  base64_encode($user.':'.$pw));  
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    $okay = curl_exec($ch);
    curl_close($ch);
    $head = ob_get_contents();
    ob_end_clean();
    $regex = '/Content-Length:\s([0-9].+?)\s/';
    $count = preg_match($regex, $head, $matches);

    if (isset($matches[1]))
        $size = $matches[1];
    else
        $size = 'unknown';
    return $size;
}




?>



Т.о. получился значительный прирост при получении файла с сервера, который ограничивает скорость отдачи. Файл размером 25 Мб заливается на сервер за 25 сек, при том, что скорость отдачи сервера не более 60 кБ/сек.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Сеть | Следующая тема »


 




[ Время генерации скрипта: 0.0683 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.