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

Как скачать файл?

Вопрос

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

если точнее, то вот эта часть кода

for chunk in response do
 --     if not options.k then
        string.gsub(chunk, "\r\n", "\n")
 --     end
      f:write(chunk)
    end

http-запросы открыты и через саму программу скачать файл получается

ах да, через response.read() получается прочитать текст кода, то есть response.read(4) возращает первые четыре символа кода

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

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


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

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

function get(url)
  local request, reason = internet.request(url)
  if not request then return '' end
 
  local text = ''
  while true do
    local data, reason = request.read()

print(data, reason)

    if not data then
      request.close()
      break
    elseif #data > 0 then
      text = text..data
    end
  end
  return text
end

эту функцию где-то находил через нее тоже не получалось сделать как надо, но там у меня в другом месте где-то был косяк. Щас поправил твой вариант, если точнее, то добавил print(data, reason) и понял в чем дело теперь:
примерно в течение полусекунды происходит следующее - программа пишет:

""      nil

""      nil

""      nil

""      nil
""      nil
""      nil
""      nil

nil      адрес

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

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

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


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

@Hikooshi какая у тебя версия оски?

и что это за куча кавычек с нилами? что они значат? Это у тебя так файлы скачиваются? или что это?

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


Ссылка на сообщение
Поделиться на других сайтах
Только что, Alex сказал:

@Hikooshi какая у тебя версия оски?

и что это за куча кавычек с нилами? что они значат? Это у тебя так файлы скачиваются? или что это?

версия 1.74, в которой еще транспозеры правильно работают)

кавычки с нилами - то, что программа принтит (обрати внимание на то, где стоит print(data, reason)), пока цикл работает. То есть в течение полусекунды запрос при неправильном айдишнике возвращает пустую строку, как и при правильном айдишнике, через полсекунды возвращает nil и адрес. То есть полсекунды data == "", reason == nil, по прошествии полусекунды data == nil, reason == адрес, выходит из цикла. При правильном айдишнике принтило бы содержимое переменной data, то есть код, полученный с пастбина

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


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

@Hikooshi а, то есть это не правильный адрес. ок.

а попробуй 1.72 оску. Там есть такая херабора со слипами? Я первый раз слышу, чтобы нужно было заслипить прогу после реквеста, чтобы хоть что-то получить в запросе. Такого же не должно быть.

 

пс. И в смысле в 1.74 транспозеры ЕЩЕ правильно работают? Их же вроде наоборот поломали в 1.73 или в 1.74, или исправили в 1.74. На 1.72 вроде они работали четенько. Там были в 1.72 какие-то микробагульки но всё в этой версии работало в основном, а армагедон начался вроде с 1.73. То аешка там отлетела, то транспозеры, а теперь еще и с реквестом оказывается какие-то чудеса несусветные происходят. Роботы пропадают и выключаются, и прочие неописуемые беды там наблюдаются в 1.74 по рассказам очевидцев.

 

Откатись на 1.72 и попробуй там файлики свои поскачивать.

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


Ссылка на сообщение
Поделиться на других сайтах
Только что, Alex сказал:

@Hikooshi а, то есть это не правильный адрес. ок.

а попробуй 1.72 оску. Там есть такая херабора со слипами? Я первый раз слышу, чтобы нужно было заслипить прогу после реквеста, чтобы хоть что-то получить в запросе. Такого же не должно быть.

 

пс. И в смысле в 1.74 транспозеры ЕЩЕ правильно работают? Их же вроде наоборот поломали в 1.73 или в 1.74, или исправили в 1.74. На 1.72 вроде они работали четенько. Там были в 1.72 какие-то микробагульки но всё в этой версии работало в основном, а армагедон начался вроде с 1.73. То аешка там отлетела, то транспозеры, а теперь еще и с реквестом оказывается какие-то чудеса несусветные происходят. Роботы пропадают и выключаются, и прочие неописуемые беды там наблюдаются в 1.74 по рассказам очевидцев.

 

Откатись на 1.72 и попробуй там файлики свои поскачивать.

ты неправильно поставил ударение на слово "еще", имелось в виду, типа "та самая версия в которой еще транспозеры работают", они поломаны были на 1.73.
После реквеста ничего можно не слипать, применяя функцию, скинутую тобой, оно само по себе слипается, потому что там цикл while и он будет выполняться до тех пор, пока в data не будет nil. В случае неправильного айдишника request.read() несколько раз будет data == "", и через полсекунды - data == nil. В случае правильного айдишника так же сначала в течение полусекунды data будет "", потом будет равна полученным данным, потом, когда файл закончится data станет nil и цикл завершится

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


Ссылка на сообщение
Поделиться на других сайтах
9 минут назад, Hikooshi сказал:

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

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

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


Ссылка на сообщение
Поделиться на других сайтах
Только что, Alex сказал:

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

да, но если слипнуть без while'а, то тоже будет работать

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


Ссылка на сообщение
Поделиться на других сайтах
21 час назад, Alex сказал:

Я первый раз слышу, чтобы нужно было заслипить прогу после реквеста, чтобы хоть что-то получить в запросе. Такого же не должно быть.

Не-не-не, все так и должно быть: read тупо пытается прочесть по кускам контент веб-страницы с сокета. Если сервак пока еще не кинул ошибку соединения, и контент отсутствует - в сокете ничего свеженького не будет, и read выдаст пустую строку. Если соединение говеное, то сокет закрывается, и read выдает nil с причиной. А если URL валидная, то и содержимое будет выдано практически мгновенно, поэтому никаких пустых строк замечено не бывает - либо бывает, но крайне редко.

 

20 часов назад, Hikooshi сказал:

да, но если слипнуть без while'а, то тоже будет работать

Потому что sleep в опеноси работает через цикл:

function os.sleep(timeout)
  checkArg(1, timeout, "number", "nil")
  local deadline = computer.uptime() + (timeout or 0)
  repeat
    event.pull(deadline - computer.uptime())
  until computer.uptime() >= deadline
end

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

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


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

Ещё можно вызвать req.finishConnect(). Эта функция выдаст true только тогда, когда установится соединение. Если там ошибка будет, эта же функция ошибку эту выкинет. Очень удобно. Можно в цикле со слипом её вызвать и ждать, пока не установится. А потом уже читать можно будет.

 

Заявления, что "никогда такого не было", ложны. Такое было давно, минимум три года. Я безумно счастлив за тех, кому не приходилось сталкиваться с этой проблемой, но на самом деле нормально работающая геталка с интернета выглядит весьма сложнее, чем код от @Alex. Если делать по-простому, то вы в свою программу добавляете бесплатное состояние гонки. Что, как известно, дебажить очень весело и интересно.

 

Ещё замечание. Чтобы не нужно было в цикле нерационально расходовать процессорное время, лучше не слип делать, а event.pull("internet_ready"). Если совсем круто хочется, то можно даже event.pull("internet_ready", req.id()).

internet_ready — это сигнал, который посылается компьютеру, если на сокете появляются новые непрочтённые данные. Например, прочла прога сначала 5 байтов с сокета, а потом на него сервер ещё двадцать отправил — тогда-то и получит прога ивент этот и снова считать данные сможет.

Так как особо крутые кодеры могут жонглировать сразу десятью интернет-соединениями на одном компьютере, полезно фильтровать ивенты по идшнику соединения, как во втором варианте у меня.

 

P. S. Все эти функции доступны при создании соединения через компонент интернет-платы. Не через либу internet. Это предельно важно. Поэтому я советую всегда не юзать либу, а помучаться, но сделать нормальную считывалку через апи компонента.

Изменено пользователем Fingercomp
плюс постскриптум

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


Ссылка на сообщение
Поделиться на других сайтах
6 часов назад, Fingercomp сказал:

Заявления, что "никогда такого не было", ложны. Такое было давно, минимум три года. Я безумно счастлив за тех, кому не приходилось сталкиваться с этой проблемой, но на самом деле нормально работающая геталка с интернета выглядит весьма сложнее, чем код от Alex...

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

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


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

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

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

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

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

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

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

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

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


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