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

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

我试过了

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

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

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

 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 

我很好奇是否有“ruby方式”。

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

看看“ OpenURI返回两个不同的对象 ”。 您可能会滥用其中的方法来中断下载/在预设限制后丢弃剩余的结果。

Interesting Posts