Download cкрипт. Как выплюнуть дробленый файл?

simplyAl

Guest
Download cкрипт. Как выплюнуть дробленый файл?

Вопрос не типичный.

Был файл file.rar весом 2.5 метра, его взяли и подробили на файлы на «сегменты»

segment1.sg - 1 метр
segment2.sg - 2й метр
segment3.sg - оставшиеся 0.5метра

Все это сохранили в базе данных. (т.е. мы знаем по какому правилу подробился файл, какие байты (начало, конец) в каком сегменте оказались).

Теперь, юзер запрашивает, например
get.php?file=file.rar

Нам нужно выплюнуть _поочередно_ файлы segment1-3.sg, причем так чтобы у юзера на компе файл сохранился в склеенном виде как file.rar.

Вариант со склеиванием "сегментов" предварительно перед их отдачей не подходит, т.к. file.rar может быть и не 2.5 метра, а гигабайта полтора - ОЗУ не хватит. Вариант забуферить склеенный файл перед отдачей на HDD тоже не подходит. Нужно именно на лету "подсовывать" сегменты юзеру.

Если юзер использует менеджер загрузки и одновременно тянет в несколько потоков – тут ничего страшного нет, просто по заголовку GET смотрим с какого места отдавать и начинаем стримить соответствующий сегмент. Тоже самое с докачкой. Вопрос в том, как отстримив 1 сегмент тут же подсунуть следующий, если никаких доп. запросов GET клиент не посылает?

Если бы можно было отслеживать, например, по какому-то событию, то 1й сегмент «ушел» клиенту, то по этому события можно было бы начинать подсовывать второй… а так – как узнать, что 1й сегмент скачан?

Юзеру через ХТТП заголовки, разумеется, выдается размер полного файла в 2.5 метра и он все время думает что именно такой файл он и качает, никаких сегментов он не видит.

Кто-нибудь может посоветовать как это сделать ПХПшным скриптом?
 

vitus

мимо проходил
достиг конца первого файла - можно начинать грузить второй, потом третий
Если бы можно было отслеживать, например, по какому-то событию, то 1й сегмент «ушел» клиенту
событие - больше нет байтов для чтения из файла :)
 

Alien

Новичок
Резюмируя.
Вопрос:
Как узнать сколько байт из N отданных сервером уже дошло до посетителя.

vitus
Скорость отдачи файла сервером как правило не равна скорости приема файла посетителем.
 

vitus

мимо проходил
Alien
а зачем нужно знать сколько уже дошло?
сливаешь в один поток последовательно, остальное http разрулит
 

simplyAl

Guest
vitus
Знать сколько дошло нужно чтобы знать когда начинать лить следующий файл. Событие по которому закончить слив понятно, не понятно по какому события начинать слив каждого последующего куска.
 

vitus

мимо проходил
:) многие знания - многие печали, ты ведь в один файл ему сливаешь, какая разница дошёл-не дошёл?
 

crocodile2u

http://vbolshov.org.ru
Да лей ты все подряд друг за другом. И совершенно незачем знать, сколько там ушло.
 

Мутник

Новичок
crocodile2u

ему же нужно, чтобы они в конце склееные были, у юзера на локальном компе....

Это вообще возможно?
 

SiMM

Новичок
> ему же нужно, чтобы они в конце склееные были, у юзера на локальном компе....
Ну и в чём проблема?
PHP:
readfile('1.dat');
readfile('2.dat');
 

simplyAl

Guest
хорошо, как оно себя будет вести на приличной загрузке? (например, 1гиг/мин, т.е. 16мег/сек)

вообще, насколько это медленней чем если бы файлы отдавались напрямую апачем (не через пхп)?

какой функцией лучше читать-выплевывать файлы, с точки здения скорости?
 

vitus

мимо проходил
1 - нормально в общем случае
2 - не заметишь разницы
3 - читать fread отдавать echo
 

simplyAl

Guest
еще вопрос:
например, если парралельно качают 100 юзеров 100 файлов, по 5 потоков одновременно кажды, и все они на модемах со скоростями 2кбпс, а файлы по 600 метров...

т.е. у меня будет 500 процессов апача крутиться да еще и в каждом по копии ПХП скрипта? так получается?
 

SiMM

Новичок
> хорошо, как оно себя будет вести на приличной загрузке?
Возьми да проверь. Надо ведь тебе, не правда ли? Результаты можешь доложить.

> вообще, насколько это медленней чем если бы файлы отдавались напрямую апачем (не через пхп)?
Медленнее. Вопрос на сколько, если подходить к нему математически, вообще не имеет смысла.

> какой функцией лучше читать-выплевывать файлы, с точки здения скорости?
А у тебя есть выбор?
> Все это сохранили в базе данных.
Хранить такой хлам в базе, конечно, врядли разумно - но это уже твои трудности.
 

simplyAl

Guest
SiMM:
я спрашиваю мнений, а не математических расчетов. Выбор есть: можно readfile, можно fopen+echo.

Ответы типа "возьми да проверь" можете вообще держать при себе.

Что до базы, а где еще хранить такой хлам? Можно в памяти держать и перечитывать из базы раз в Х запросов, чтобы не обращаться в базе по каждому запросу.
 

vitus

мимо проходил
100 юзеров 100 файлов, по 5 потоков одновременно кажды, и все они на модемах со скоростями 2кбпс, а файлы по 600 метров...
столько психов сразу :) а серверу твоему IMHO наплевать какая у них скорость, если он не ждёт гипотетических событий

-~{}~ 15.03.05 19:20:

Ответы типа "возьми да проверь" можете вообще держать при себе.
это был правильный ответ
 

SiMM

Новичок
> Выбор есть: можно readfile, можно fopen+echo.
> Все это сохранили в базе данных.
Ты уж определись - в базе твои данные или в файлах - не морочь нам голову.

> я спрашиваю мнений, а не математических расчетов.
На 20 мкс. Тебе легче стало? Ты хоть понимаешь, что на сколько - зависит от мощности сервера и его загрузки в текущий момент времени?
 

Alien

Новичок
например, если парралельно качают 100 юзеров 100 файлов, по 5 потоков одновременно кажды, и все они на модемах со скоростями 2кбпс, а файлы по 600 метров...
логично предположить, что висит 500 копий апача, и в каждом ~600 мег данных. как с этим веб-сервер справится - мне тоже интересно.
 

simplyAl

Guest
vitus
серверу наплевать абсолютно, НО если child процесс апачевский умирает только тогда, когда файл полностью отдан (а я думаю так это и есть), то у меня будет много процессов долго и нудно ждать пока юзеры примут файлы - в результате ОЗУ может не хватать.

насколько я помню апач не умеет обрабатывать несколько запросов одним процессом _одновременно_? он умеет убивать child'а после обработки Х запросов...

-~{}~ 15.03.05 19:27:

Alien
если у него в каждом процессе по 600 метров данных то можно сразу вешаться:).

апач когда стримит файл, он ведь НЕ весь его целиком в буфер берет? по идее он должен считывать Х байт, отдавать, считывать следующие Х байт и т.д.

но даже если он в памяти сами данные не буферит полностью, все равно 500 процессов с 500-700 метров памяти отъедят...

-~{}~ 15.03.05 19:31:

Автор оригинала: SiMM
> Выбор есть: можно readfile, можно fopen+echo.
> Все это сохранили в базе данных.
Ты уж определись - в базе твои данные или в файлах - не морочь нам голову.
Я имел ввиду, что правила по которым разбили файлы хранятся в базе данных, т.е. начало-конец каждого сегмента и списко сегментов. Сами файлы на диске разумеется.

Автор оригинала: SiMM
> я спрашиваю мнений, а не математических расчетов.
На 20 мкс. Тебе легче стало? Ты хоть понимаешь, что на сколько - зависит от мощности сервера и его загрузки в текущий момент времени?
не надо понтов этих. Ответы предполагались: "значительно", "не значительно", "в разы", "не заметишь" и т.д. Впрочем, мне уже ответили.
 

confguru

ExAdmin
Команда форума
simplyAl

Надо задумыватся о аналоге P2P
PHP не предназначен отдавать большие массивы chunkaми :)
Я встречал - то что за сессию отдается не более 5 файлов
причем - запросы хранятся.
А если сервер уже нагружен - т.е. уже много скачек - то он просто не дает качать|войти..

-~{}~ 15.03.05 19:37:

Disposition: attachment
 
Сверху