如何通过HTTP下载只有ruby的大文件

时间:2009-07-13 15:58:13

标签: ruby http fetch

我只需要通过HTTP下载文件的前几千字节。

我试过

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

但实际上它下载了整个文件。

3 个答案:

答案 0 :(得分:4)

这在使用套接字时似乎有效:

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

我很好奇是否有“红宝石”。

答案 1 :(得分:4)

这是一个老话题,但根据我的研究,它仍然是一个似乎无法回答的问题。这是我通过猴子修补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

救援捕获了过早调用HTTP.finish时引发的IOError。

仅供参考,HTTPResponse对象中的套接字不是真正的IO对象(它是一个名为BufferedIO的内部类),但它也非常容易进行修补。 ,模仿你需要的IO方法。例如,我正在使用的另一个库(exifr)需要readchar方法,这很容易添加:

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

答案 2 :(得分:0)

查看“OpenURI returns two different objects”。您可能会滥用其中的方法来中断下载/在预设限制后丢弃剩余的结果。