Як можна реалізувати багатосекційне закачування файлу за http
Як можна реалізувати багатосекційне завантаження файлу по http протоколу?
Його вивчивши. В особі поля заголовка Range.
А якщо просто, чи можна це зробити за допомогою TidHTTP (Indy) або THTTPCli (ICS)?
TIdHTTP має відповідні властивості.
> У TIdHTTP є відповідні характеристики. Це все зрозуміло, але як організувати кілька одночасних скачок і щоб це все писати в один файл?
Наскільки я зрозумів багато хто знає відповідь але неохоче діляться їм:) Полазив трохи по інету, поколупав бібліотеку ICS, і дійшов висновку: для мультисекційного закачування необхідно: 1) відкрити файл на диску (TFileStream) 2) створити масив з TidHTTP (кількість їх дорівнює кількості секцій) 3) кожному елементу TidHTTP у властивості. 4) кожен елемент TidHTTP доведеться запускати в окремому потоці тут напрошується питання при зриві накачування як визначити який сегмент наскільки закачаний, при одній секції все зрозуміло, а як бути якщо секцій 5?
тут напрошується питання при зриві закачування як визначити який сегмент наскільки закачано, при одній секції все зрозуміло, а як бути якщо секцій 5?
Запізніле питання. При зриві закачування вже пізно метатися. Ще при старті потоків, кожен повинен знати звідки і доки йому слід запитувати рейндж.
Усі, крім пункту 4, для ICS потоки не потрібні, оскільки він підтримує модель подію.
> при одній секції все зрозуміло, а як бути, якщо секцій 5?
Читати з файлу, в якому закачуєш.
> Усі, крім пункту 4, для ICS потоки не потрібні,
Так вони й ведутьсебе в потоці не завжди передбачувано.
> Та вони і поводяться в потоці не завжди передбачувано.
У багатьох таке з потоками навіть без використання ICS
Реалізація на ICS не цікавить, оскільки там це вже все є компонентом TMultipartHttpDownloader, але . Цікава реалізація на TidHTTP. Я по-моєму включився в технологію але не можу збагнути як реалізувати дозакачування при використанні декількох секцій. Може якось пробігтися по файлу і визначити де у файлі є дані, а де ні, адже писати то кожну секцію буду у певне місце?
бо там вже є все компонент TMultipartHttpDownloader але .
А яке він має відношення до сабжу?
Може якось пробігтися по файлу і визначити де у файлі є дані, а де ні, адже писати то кожну секцію буду у певне місце?
Коли стартує перше закачування, то ніякого файлу ще немає. А рейндж вже час вказувати. А вказавши рейндж для потоку, треба його запам'ятати, щоб потім не ворзникало думок "по файлу бігати"
> Коли стартує перше завантаження, то ніякого файлу ще немає. > А рейндж уже час вказувати. > А вказавши рейндж для потоку, треба його запам'ятати, щоб потім не ворзникало думок "по файлу бігати"Як це файлу немає, будемо качати в пам'ять? треба, але в параметрах 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", отримав розмір ресурсу. > створив локальний файл вказаного розміру. > поділив розмір на кількість секцій, визначив межі секцій. > > створив потоки, сказав їм звідки качати, скільки качати, > і починаючи звідки качати.> все! > потік знає звідки брати дані і куди їх складати.Наскільки я розумію всі потоки повинні працювати з єдиним покажчиком на файл?
то всі потоки повинні працювати з єдиним покажчиком на файл?
залежить від особистих політичних поглядів. можуть і з одним, а можуть і з окремими темповими файлами.
Дозакачування повинен забезпечувати сервер, йому треба повідомити який діапазон існує.
Наскільки я зрозумів, то якщо вказати рейндж наприклад 100-500, то компонет idHTTP запише відповідно завантажене у файл з позиції 100 і по 500? сегментів і початок і кінець кожного сегмента для кожної закачки або переглядати якимось чином файл для визначення кількості скачаних шматків.
то компонет idHTTP запише відповідно завантажене у файл з позиції 100 і 500?
Він нічого не знає ні про які такі "позиції"
idHTTP запише відповідно завантажене у файлз позиції 100 і 500?
але не з позиції 100, навіть якщо це значення було в заголовку запиту.
може, у кого є приклад?
приклад чого? трьох арифметичних операцій складання віднімання та поділу?
> Наскільки я зрозумів, якщо вказати рейндж наприклад 100-500, > то компонет idHTTP запише відповідно завантажене файл > з позиції 100 і 500?Хіба він пише у файл?
> Хіба він пише у файл?А куди якщо не у файл? можна звичайно в TMemoryStream але ну його нафіг тримати в пам'яті 4 гіговий файл.
Він пише у стриму, а не у файл.
Спробую узагальнити почуте: Завдання закачати файл 100 байт у дві секції в один файл (не створюємо кілька тимчасових). Отримуємо заголовок запиту для визначення розміру файлу. 3) створюємо перший потік для idhttp де встановлюємо рендж з 0 по 50 4) встановлюємо позицію запису у файл на початок (необов'язково) 5) робимо геть запит 6) створюємо другий потік для idhttp де встановлюємо рендж з 51 до 100 7) встановлюємо позицію запису з 51 байта 8) робимо геть запит
пункти 4 і 7 під сумнівом оскільки невідомо як поведеться запис при одночасному зверненні двох потоків до одного файлу.
бо невідомо як поведеться запис при одночасному зверненні двох потоків до одного файлу
←→FireMan_Alexey (2009-02-03 14:32) [31]
Якщо компонент пише у стрім у тебе є розмір записаного.
←→FireMan_Alexey (2009-02-03 14:34) [32]
А коли закачування розривається, у стримі є позиціязвідки качати далі називається TMemoryStream.SIZE :)
> А коли закачування розривається, у стримі є позиція, звідки > Це ясно, а як визначити після аварійного перезавантаження програми скільки секцій було в закачуванні і скільки закачано в кожній сесії? Виходить треба десь зберігати окремо інформацію про кількість і початок та обсяг кожної секції.
Це ясно, а як визначити після аварійного перезавантаження програми, скільки секцій було в закачуванні і скільки завантажено в кожній сесії? Виходить треба десь зберігати окремо інформацію про кількість і початок та обсяг кожної секції.
←→FireMan_Alexey (2009-02-04 15:28) [36]
А у Download Master-a ще файл *.dfmr є:)
Так треба доглядати цю інформацію
> А у Download Master-a ще файл *.dfmr є :)Наскільки я знаю, DM пише інфу про секції в кінець того файлу, що закачує.
←→FireMan_Alexey (2009-02-05 03:38) [39]
Зараз ні А раніше був :), я по старій пам'яті :)