Как скачать по HTTP только кусок большого файла с помощью ruby - PullRequest
5 голосов
/ 13 июля 2009

Мне нужно только загрузить первые несколько килобайт файла через HTTP.

Я пытался

require 'open-uri'
url = 'http://example.com/big-file.dat'
file = open(url)
content = file.read(limit)

Но на самом деле он загружает полный файл.

Ответы [ 3 ]

4 голосов
/ 13 июля 2009

Это похоже на работу при использовании сокетов:

require 'socket'                  
host = "download.thinkbroadband.com"                 
path = "/1GB.zip" # get 1gb sample file
request = "GET #{path} HTTP/1.0\r\n\r\n"
socket = TCPSocket.open(host,80) 
socket.print(request)        

# find beginning of response body
buffer = ""                    
while !buffer.match("\r\n\r\n") do
  buffer += socket.read(1)  
end           

response = socket.read(100) #read first 100 bytes of body
puts response

Мне любопытно, есть ли "рубиновый путь".

4 голосов
/ 22 декабря 2011

Это старая ветка, но, по моим исследованиям, этот вопрос все еще остается без ответа. Вот решение, которое я придумал, немного исправив Net :: HTTP:

require 'net/http'

# provide access to the actual socket
class Net::HTTPResponse
  attr_reader :socket
end

uri = URI("http://www.example.com/path/to/file")
begin
  Net::HTTP.start(uri.host, uri.port) do |http|
    request = Net::HTTP::Get.new(uri.request_uri)
    # calling request with a block prevents body from being read
    http.request(request) do |response|
      # do whatever limited reading you want to do with the socket
      x = response.socket.read(100);
    end
  end
rescue IOError
  # ignore
end

Спасатель ловит IOError, который выдается при преждевременном вызове HTTP.finish.

К вашему сведению, сокет в объекте HTTPResponse не является истинным объектом IO (это внутренний класс с именем BufferedIO), но довольно просто сделать обезьяну-патч, которая тоже имитирует IO методы, которые вам нужны. Например, другая библиотека, которую я использовал (exifr), нуждалась в методе readchar, который было легко добавить:

class Net::BufferedIO
  def readchar
    read(1)[0].ord
  end
end
0 голосов
/ 13 июля 2009

Проверить " OpenURI возвращает два разных объекта ". Возможно, вы сможете использовать методы, используемые там, чтобы прервать загрузку / выбросить оставшуюся часть результата после заданного ограничения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...