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
「ルビーウェイ」があるのか気になります。
これは古いスレッドですが、私の調査によると、まだほとんど答えられていないように思われる質問です。これは、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は2つの異なるオブジェクトを返す」を確認してください。そこにあるメソッドを悪用して、事前設定された制限の後にダウンロードを中断したり、結果の残りを破棄したりできる場合があります。