Cómo descargar vía HTTP solo pieza de archivo grande con ruby

Solo necesito descargar los primeros kilobytes de un archivo a través de HTTP.

Lo intenté

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

Pero en realidad descarga el archivo completo.

Esto parece funcionar cuando se usan sockets:

 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 

Tengo curiosidad por si hay una “manera Ruby”.

Este es un hilo antiguo, pero sigue siendo una pregunta que parece mayormente sin respuesta según mi investigación. Aquí hay una solución que se me ocurrió con el parche de red Net :: HTTP un poco:

 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 

El rescate captura el IOError que se lanza cuando se llama HTTP.finish prematuramente.

Para su información, el zócalo dentro del objeto HTTPResponse no es un verdadero objeto IO (es una clase interna llamada BufferedIO ), pero es bastante fácil aplicar un parche que también imita los métodos IO que necesita. Por ejemplo, otra biblioteca que estaba usando (exifr) necesitaba el método readchar , que era fácil de agregar:

 class Net::BufferedIO def readchar read(1)[0].ord end end 

Echa un vistazo a ” OpenURI devuelve dos objetos diferentes “. Es posible que pueda abusar de los métodos para interrumpir la descarga / desechar el rest del resultado después de un límite preestablecido.

    Intereting Posts