-
Как можно реализовать многосекционную закачку файла по http протоколу?
-
Его изучив. В лице поля заголовка Range.
-
А если по простому, можно ли это сделать с помощью TidHTTP (Indy) или THTTPCli (ICS)?
-
У TIdHTTP есть соотвествующие свойства.
-
> У TIdHTTP есть соотвествующие свойства.
Это все понятно, но как организовать несколько одновременных скачек и чтоб это все писать в один файл?
-
несколько idhttp
-
Насколько я понял многие знают ответ но неохотно делятся им:)
Полазил немного по инету, поковырял библиотеку ICS, и пришел к выводу:
для мультисекционной закачки необходимо:
1) открыть файл на диске (TFileStream)
2) создать массив с TidHTTP (количество их равно количеству секций)
3) каждому элементу TidHTTP в свойстве .Reques.Range или .Reques.ContentRangeStart и .Reques.ContentRangeEnd (еще не разобрался) присваиваем этим свойствам соответствующие сегменты файла
4) каждый элемент TidHTTP придется запускать в отдельном потоке
тут напрашивается вопрос при срыве закачки как определить какой сегмент насколько закачан, при одной секции все понятно, а как быть если секций 5?
-
тут напрашивается вопрос при срыве закачки как определить какой сегмент насколько закачан, при одной секции все понятно, а как быть если секций 5?
запоздалый вопрос.
при срыве закачки уже поздняк метаться.
еще при старте потоков, каждый должен знать откуда и докуда ему следует запрашивать рейндж.
-
> Usov (29.01.2009 10:25:06) [6]
Все, кроме пункта 4, для ICS потоки не нужны, так как он поддерживает событийную модель.
-
> при одной секции все понятно, а как быть если секций 5?
Читать из файла в которой закачиваешь.
> Все, кроме пункта 4, для ICS потоки не нужны,
Да они и ведут себя в потоке не всегда предсказуемо.
-
> tesseract (29.01.2009 11:53:09) [9]
> Да они и ведут себя в потоке не всегда предсказуемо.
У многих такое c потоками даже без использования ICS
-
Реализация на ICS не интересует так как там это уже все есть компонент TMultipartHttpDownloader но .
Интересна реализация на TidHTTP. Я помоему врубился в технологию но не могу сообразить как реализовать дозакачку при использовании нескольких секций. Может как то пробежаться по файлу и определить где в файле есть данные а где нет, ведь писать то каждую секцию буду в определенное место?
-
так как там это уже все есть компонент TMultipartHttpDownloader но .
А какое он имеет отношение с сабжу?
Может как то пробежаться по файлу и определить где в файле есть данные а где нет, ведь писать то каждую секцию буду в определенное место?
Когда стартует первая закачка, то никакого файла еще нет.
А рэйндж уже пора указывать.
А указав рейндж для потока, надо его запомнить, чтобы потом не ворзникало мыслей "по файлу бегать"
-
> Когда стартует первая закачка, то никакого файла еще нет.
> А рэйндж уже пора указывать.
> А указав рейндж для потока, надо его запомнить, чтобы потом не ворзникало мыслей "по файлу бегать"
Как это файла нет, будем качать в память?
Рейндж я согласен указывать обязательно до GET запрса надо, но в параметрах GET я указываю куда idhttp будет складывать полученные данные, то есть TFileStrim.
-
Как это файла нет, будем качать в память?
Он у тебя появлется еще до того, как запрос на файл на сервер уйдет?
-
выполнил первый запрос "head", получил размер ресурса.
создал локальный файл указанного размера.
поделил рамер на количество секций, определил границы секций.
создал потоки, сказал им откуда качать, сколько качать, и начиная откуда качать.
все!
поток знает откуда брать данные и куда их складывать.
-
> Он у тебя появлется еще до того, как запрос на файл на сервер
> уйдет?
Фактически да
var
fs: TFileStream;
begin
fs := TFileStream.Create('c:\test.avi', fmCreate);
...
колдуем с ранджем
...
idHTTP.Get('
http://anysite.com/test.avi', fs);
end
-
> выполнил первый запрос "head", получил размер ресурса.
> создал локальный файл указанного размера.
> поделил рамер на количество секций, определил границы секций.
>
> создал потоки, сказал им откуда качать, сколько качать,
> и начиная откуда качать.
> все!
> поток знает откуда брать данные и куда их складывать.
Насколько я понимаю то все потоки должны работать с единым указателем на файл?
-
то все потоки должны работать с единым указателем на файл?
зависит от личных политических взглядов.
могут и с одним, а могут и с отдельными темповыми файлами.
-
> Usov (29.01.2009 13:02:11) [11]
Дозакачку должен обеспечивать сервер, ему только надо сообщить какой диапазон существует.
-
Насколько я понял, то если указать рейндж например 100-500, то компонет idHTTP запишет соответствено скачаное в файл с позиции 100 и по 500?
Получается для того чтоб дозакачать прерванную закачку надо:
или где то хранить информацию о количестве сегментов и начало и конец каждого сегмента для каждой закачки
или просматривать каким то образом файл для определения количества скачанных кусков.
-
то компонет idHTTP запишет соответствено скачаное в файл с позиции 100 и по 500?
Он ничего не знает ни про какие такие "позиции"
-
idHTTP запишет соответствено скачаное в файл с позиции 100 и по 500?
с какого перепугу?
он запишет скачиваемое либо по указанному адресу буфера, начиная с его начала, либо в текущую позицию потока, если в метод был передан поток.
но никак не с позиции 100, даже если это значение было в заголовке запроса.
-
может у кого есть пример?
-
пример чего?
трех арифметических операций сложения вычитания и деления?
-
> Насколько я понял, то если указать рейндж например 100-500,
> то компонет idHTTP запишет соответствено скачаное в файл
> с позиции 100 и по 500?
Разве он пишет в файл?
-
> Разве он пишет в файл?
А куда если не в файл? можно конечно в TMemoryStream но ну его нафиг держать в памяти 4 гиговый файл.
-
Он пишет в стрим, а не в файл.
-
Попытаюсь обобщить услышанное:
Задача закачать файл 100 байт в две секции в один файл (не создаем несколько временных).
1) получаем заголовок запроса для определения размера файла
2) создаем файловый поток для файла
3) создаем первый поток для idhttp где устнавливаем рендж с 0 по 50
4) устанавливаем позицию записи в файл в начало (необязательно)
5) делаем гет запрос
6) создаем второй поток для idhttp где устнавливаем рендж с 51 до 100
7) устанавливаем позицию записи с 51 байта
8) делаем гет запрос
пункты 4 и 7 под сомнением так как неизвестно как поведет себя запись при одновременном обращении двух потоков к одному файлу.
жду комментов и предложений
-
так как неизвестно как поведет себя запись при одновременном обращении двух потоков к одному файлу
кому неизвестно?
-
> кому неизвестно?
конечно же мне:)
-
Если компонент пишет в стрим у тебя есть размер записанного!!!
Создай 5 Мем стримов и призакачке проверяй на заполнение скажем по 128Кб и по заполнению кидай их на винт :)
-
А когда закачка разрывается, в стриме есть позиция откуда качать дальше называется TMemoryStream.SIZE :)
-
> А когда закачка разрывается, в стриме есть позиция откуда
> качать дальше называется TMemoryStream.SIZE :)
Это ясно, а как определить после аварийной перезагрузки программы сколько секций было в закачке и сколько закачано в каждой сессии? Получается надо где-то хранить отдельно информацию о количестве и начале и объеме каждой секции.
-
> Usov (04.02.2009 14:20:33) [33]
Получается так
-
Это ясно, а как определить после аварийной перезагрузки программы сколько секций было в закачке и сколько закачано в каждой сессии? Получается надо где-то хранить отдельно информацию о количестве и начале и объеме каждой секции.
ну ты догада.
-
А у Download Master-a еще файл *.dfmr есть :)
-
> Медвежонок Пятачок (04.02.2009 14:42:35) [35]
Так созранять надо эту информацию
-
> А у Download Master-a еще файл *.dfmr есть :)
Насколько я знаю, DM пишет инфу о секциях в конец того файла что закачивает.
-
Сейчас нет
А раньше был :), я по старой памяти :)
-
> Usov © (04.02.09 23:56) [38]
> Насколько я знаю, DM пишет инфу о секциях в конец того файла что закачивает.
Хм, ну тоже прикольно придумано. Потом подрубить файл - и все. Чистенько и "ничего лишнего".
-
> Хм, ну тоже прикольно придумано. Потом подрубить файл -
> и все. Чистенько и "ничего лишнего".
Только если сорвется на последних байтах закачка - хана всему файлу.
-
> Только если сорвется на последних байтах закачка - хана
> всему файлу.
В смысле?
Докачаеш :)
Ты же для этого и секции вводиш.
-
> > Только если сорвется на последних байтах закачка - хана
> > всему файлу.
>
>
> В смысле?
> Докачаеш :)
> Ты же для этого и секции вводиш.
>
Всмысле если хранить инфу о секциях в конце файла.
-
Сделай Head, получи размер, зарезервируй место на диске и вперед :)
А информацию можеш хранить вконце файла.
А если даже и двигать, то информацию можно достать размер файла - размер блока параметров секций.
-
Удалено модератором
Примечание: СПАМ
-
> Господа знатоки ICS
нфига быть знатоком, нужно просто читать внмательней
> Реализация на ICS не интересует так как там это уже все есть компонент TMultipartHttpDownloader
или дело принципа? ну так посмотри в исходники.
-
> sniknik © (26.10.09 01:19)
ты на дату сабжа смотрел? ;)
-
> ты на дату сабжа смотрел? ;)
а ты смотрел на дату поста на который у меня ответ?
-
тема актуальна еще, просто руки никак не доходят заняться реализацией.
-
>Может как то пробежаться по файлу и определить где в файле есть данные а где нет, ведь писать то каждую секцию буду в определенное место?
1. Создавать файл в каком-то своём формате, после полного приёма пересобирать файл.
2. Создавать дополнительный файл с указанием что скачалось или что не скачалось.
3. Запоминать данные о закачках в базе данных.
4. Запоминать данные о закачках в реестре.
Выбирай.