Перейти к содержимому
  • 0
HeroBrine1st

Как узнать размер файла на сервере и скачивать его по байту?

Вопрос

Короче мне надо сделать скачку файлов как в любом загрузчике для виндовса - итоговый размер файла, название и сколько осталось до конца скачивания. костыли через internet.connect не работают.

 

можно узнать скорость интернета через скачивание файла весом в 1024 байт, но нельзя узнать размер файла.

 

А я прямо горю желанием сделать диспетчер загрузок, ведь мой браузер как-то видит размер файла до закачки

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

Собственно ответ из прошлой темы : 

com = require("component")
net = com.internet
 
req = net.request("https://pp.userapi.com/c638822/v638822414/2d563/6UNAy7oum-w.jpg") --первая встречная картинка, если че не реклама)
print(req)
responce = {req.response()} 
print(require("serialization").serialize(responce))
os.sleep(1)
s=req.read()
print(#s)
--[[repeat 
	 
if s then 
	print( #s ) 
end 
until not s]]

Пишет таблицу, а если коммент уберешь, то и размеры кучу раз выпишет. http://c2n.me/3JGEwQg

UDP

Как выяснилось этот код только в эмуляторе нормально работает.
так что ищите другое решение для ОС который в кубаче.

Изменено пользователем MeXaN1cK

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По идее, для того, чтобы узнать размер загружаемого файла, надо смотреть значение хидера Content-Length в HTTP запросе.

Как это сделать?

Думаю, можно воспользоваться методом response():number, string, table на объекте HTTP-запроса. Он как раз должен вернуть таблицу хидеров в конце.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как узнать размер файла на сервере и скачивать его по байту?

А по байту-то скачивать зачем? Интернет слишком быстрый?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А по байту-то скачивать зачем? Интернет слишком быстрый?

но ведь если скачивать по чанкам, то скачивается пустой текст вида "", и только потом по чанкам весь текст

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По идее, для того, чтобы узнать размер загружаемого файла, надо смотреть значение хидера Content-Length в HTTP запросе.

Как это сделать?

Думаю, можно воспользоваться методом response():number, string, table на объекте HTTP-запроса. Он как раз должен вернуть таблицу хидеров в конце.

то есть responce.number() возвратил эти три значения, и что мне делать с таблицей то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

то есть responce.number() возвратил эти три значения, и что мне делать с таблицей то?

 

Как что? Это и есть таблица всех хидеров запроса.

Теперь покопайся в ней и найди нужный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По идее, для того, чтобы узнать размер загружаемого файла, надо смотреть значение хидера Content-Length в HTTP запросе. Как это сделать? Думаю, можно воспользоваться методом response():number, string, table на объекте HTTP-запроса. Он как раз должен вернуть таблицу хидеров в конце.

Можно, но содержимое заголовка формируется сервером, и если он не захочет, то Content-Length не выдаст даже под пытками.

 

Вот пример кода:

com = require("component")
net = com.internet

req = net.request("https://ya.ru")
print( ({req.response()})[3]['Content-Length'][1] )
repeat s=req.read() if s then print( #s ) end until not s
Выдаст общую длину, а потом длины чанков. Сумма длин чанков должна совпасть с длиной в заголовке.

Но, например в заголовках ответа на запрос к "http://google.com"Content-Length отсутствует.

 

но ведь если скачивать по чанкам, то скачивается пустой текст вида "", и только потом по чанкам весь текст

И как это мешает?

 

Данные в сети передаются пакетами разной длины. Можно, конечно, передавать в пакете по одному байту данных, но это крайне затратный способ.

 

Не знаю, почему принимаются пустые чанки, но они влияют только на количество чанков, а в остальном никак не мешают. Считать количество чанков нет никакого смысла. Для оценки времени до окончания загрузки имеют значение только длины чанков, но...

 

ведь мой браузер как-то видит размер файла до закачки

Мой тоже видит. Но не всегда. Если сервер не захочет, то и браузер будет в неведении до самого конца загрузки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно, но содержимое заголовка формируется сервером, и если он не захочет, то Content-Length не выдаст даже под пытками.

 

Вот пример кода:

com = require("component")
net = com.internet

req = net.request("https://ya.ru")
print( ({req.response()})[3]['Content-Length'][1] )
repeat s=req.read() if s then print( #s ) end until not s
Выдаст общую длину, а потом длины чанков. Сумма длин чанков должна совпасть с длиной в заголовке.

Но, например в заголовках ответа на запрос к "http://google.com"Content-Length отсутствует.

 

И как это мешает?

 

Данные в сети передаются пакетами разной длины. Можно, конечно, передавать в пакете по одному байту данных, но это крайне затратный способ.

 

Не знаю, почему принимаются пустые чанки, но они влияют только на количество чанков, а в остальном никак не мешают. Считать количество чанков нет никакого смысла. Для оценки времени до окончания загрузки имеют значение только длины чанков, но...

 

Мой тоже видит. Но не всегда. Если сервер не захочет, то и браузер будет в неведении до самого конца загрузки.

 

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

 

И вычислять скорость скачивания я должен по тому, какая длина чанка скачалась за определенное время? 

 

Т.е. по формуле U = S/T, где U - скорость, S - длина чанка, а T - время?

Изменено пользователем HeroBrine1st

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

то есть я должен вычитать длину чанков из общей длины чанков, и как эта длина закончится, то файл скачан, верно?

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

 

и из-за пустых чанков мой браузер может ожидать столько времени до начала скачки что ли?

Любой браузер сколько-то времени ждёт как до начала загрузки страницы, так и до конца. Информация по сети передаётся пакетами. Если содержимое файла не вмещается в один пакет, то оно разбивается на несколько пакетов. Проходя по такой сложной сети, как Интернет, пакеты поступают в браузер с задержкой, причем неравномерной. Пакеты, потерявшиеся в пути, могут высылаться повторно. Теоретически, первый пакет может прийти позже остальных. На стороне клиента пакеты могут требовать упорядочения, дешифровки и декомпрессии, но то, что тебе выдаёт интернет-карта OpenComputers – это уже переработанная, буферизованная и готовая к использованию информация. Просто последовательно читай то, что она выдаёт. Требуется ждать – жди. Твой браузер тоже ждёт, и пакеты он получает тоже неравномерно.

 

И вычислять скорость скачивания я должен по тому, какая длина чанка скачалась за определенное время?    Т.е. по формуле U = S/T, где U - скорость, S - длина чанка, а T - время?

Как я уже говорил, интернет-карту можно рассматривать как буфер, и ты не можешь точно узнать, какой чанк за какое время скачался, а если бы и знал точно, то неравномерное поступление пакетов из интернет-сети тоже не позволило бы тебе использовать эту формулу напрямую. Браузер не знает реальной скорости интернета, так как для него пакет приходит практически мгновенно. Не было пакета, и вдруг он пришёл! В пакете приходит не один байт, а сразу много, 1500 байт примерно.

 

Переводя в термины OpenComputers: ты читаешь очередной чанк, а он пустой. Читаешь еще один, а он тоже пустой. На очередном тике ты получаешь долгожданный чанк, а потом снова ждешь. Поэтому в реальных браузерах и менеджерах закачки используется усреднение. Например, измеряешь, сколько байт пришло за последнюю секунду. Это позволит стрелке спидометра не скакать от нуля до бесконечности, а выдавать понятные для человека показания. А если скорость не очень нестабильная, и стрелка спидометра продолжает метаться, то можно увеличить интервал времени до нескольких секунд.

Изменено пользователем eu_tomat

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно, но содержимое заголовка формируется сервером, и если он не захочет, то Content-Length не выдаст даже под пытками.

 

Вот пример кода:

com = require("component")
net = com.internet

req = net.request("https://ya.ru")
print( ({req.response()})[3]['Content-Length'][1] )
repeat s=req.read() if s then print( #s ) end until not s
Выдаст общую длину, а потом длины чанков. Сумма длин чанков должна совпасть с длиной в заголовке.

Но, например в заголовках ответа на запрос к "http://google.com"Content-Length отсутствует.

 

И как это мешает?

 

Данные в сети передаются пакетами разной длины. Можно, конечно, передавать в пакете по одному байту данных, но это крайне затратный способ.

 

Не знаю, почему принимаются пустые чанки, но они влияют только на количество чанков, а в остальном никак не мешают. Считать количество чанков нет никакого смысла. Для оценки времени до окончания загрузки имеют значение только длины чанков, но...

 

Мой тоже видит. Но не всегда. Если сервер не захочет, то и браузер будет в неведении до самого конца загрузки.

 

пишет ошибку, что не может вызвать метод responce т.к. он nil. менять url пробовал, не помогает.

com = require("component")
net = com.internet
 
req = net.request("https://pp.userapi.com/c638822/v638822414/2d563/6UNAy7oum-w.jpg") --первая встречная картинка, если че не реклама)
print(req)
responce = {req.responce()} 
print(require("serialization").serialize(responce))
os.sleep(1)
repeat s=req.read() if s then print( #s ) end until not s

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно, но содержимое заголовка формируется сервером, и если он не захочет, то Content-Length не выдаст даже под пытками.

 

Вот пример кода:

com = require("component")
net = com.internet

req = net.request("https://ya.ru")
print( ({req.response()})[3]['Content-Length'][1] )
repeat s=req.read() if s then print( #s ) end until not s
Выдаст общую длину, а потом длины чанков. Сумма длин чанков должна совпасть с длиной в заголовке.

Но, например в заголовках ответа на запрос к "http://google.com"Content-Length отсутствует.

 

И как это мешает?

 

Данные в сети передаются пакетами разной длины. Можно, конечно, передавать в пакете по одному байту данных, но это крайне затратный способ.

 

Не знаю, почему принимаются пустые чанки, но они влияют только на количество чанков, а в остальном никак не мешают. Считать количество чанков нет никакого смысла. Для оценки времени до окончания загрузки имеют значение только длины чанков, но...

 

Мой тоже видит. Но не всегда. Если сервер не захочет, то и браузер будет в неведении до самого конца загрузки.

 

ошибку нашел. response а не responce. код вроде у тебя скопировал. как буква поменялась - понятия не имею, я скопировал метод и перенес в переменную ведь

Изменено пользователем HeroBrine1st

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну конечно. В чудном английском языке слово называется response.

в любом случае оно возвращает вместо таблицы пустую таблицу {}. пробовал даже с гитхаба скачать, который 100% возвращает content-length, но нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

response метод возвращает nil и на гитхабе, и на яндексе, и в гугле, везде просто.

 

код наипростейший - local a = b.request("ya.ru")

local c = a.response(), b - component.internet

 

длины чанков получаются прекрасно через string.len, а общая длина до загрузки никак

Изменено пользователем HeroBrine1st

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как узнать размер файла на сервере 2 (ибо на первый не отвечают)

 

response метод возвращает nil и на гитхабе, и на яндексе, и в гугле, везде просто.

 

код наипростейший - local a = b.request("ya.ru")

local c = a.response(), b - component.internet

 

длины чанков получаются прекрасно через string.len, а общая длина до загрузки никак

Создание еще одной темы не повысит твои шансы на получение ответа. Новая тема будет либо удалена, либо объединена со старой. В первой теме никто не отвечает, потому что твои последние посты не содержат вопроса. Есть лишь утверждения без конкретного кода.

 

Что должен делать твой «простейший код», вообще не понятно. Получать длину файла из заголовка? Так он этого не делает. А я уже показал, как получить длину файла из заголовка Код рабочий при условии, что сервер сразу же отдаёт Content-Length.

 

Как я уже говорил, сайт может вообще не отдать длину, как например, для http://google.com/

 

В случае страницы http://ya.ru мой код не работает потому, что страница по этому адресу не содержит контента, длина его нулевая, зато код ответа указывает на необходимость повторить запрос, но уже для нового адреса https://ya.ru, для которого уже возвращается нормальная длина в заголовке.

 

Что тебе мешает проанализировать информацию, возвращенную сайтом?

 

69gYVbM.png

 

Видно, что код ответа 302, что означает переадресацию на новую страницу. Вытаскивай новый url из Location и повторяй запрос, который в нашем случае будет успешен, но это не обязательно. Возможна следующая переадресация, или страница может быть вообще не найдена. А если найдена, то не обязательно её длина будет сообщена в заголовке.

 

tiGKSgU.png

 

 

Не забудь почитать про коды ответов HTTP-сервера

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@@eu_tomat, тестишь в эмуляторе или настоящем ОС?

 

Почемуто из майнкрафта у меня тоже выдаёт только nil. Либоя я делаю что-то не то, либо в OC HTTP запросы сломаны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@@eu_tomat, тестишь в эмуляторе или настоящем ОС?

 

Почемуто из майнкрафта у меня тоже выдаёт только nil. Либоя я делаю что-то не то, либо в OC HTTP запросы сломаны.

Всё проверялось в настоящем OpenComputers-MC1.7.10-1.6.2.12-universal.jar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну естественно, что в кубаче работать ну будет. Интернет-карта же у нас мгновенно подключается, да?

Нет.

 

И .read у нас читает сразу все эн мегабайт?

Ну ясен пень, что нет.

 

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

Изменено пользователем Fingercomp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Читай правила.

3.1.10 Запрещено создавать дубли тем.
Если вы случайно создали дубль темы – воспользуйтесь кнопкой "Жалоба" под сообщением и попросите удалить лишнюю тему.

Изменено пользователем qwertyMAN

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...