2009-07-13 16 views
5

के साथ HTTP फ़ाइल के माध्यम से केवल बड़ी फ़ाइल के टुकड़े को डाउनलोड करने के लिए मुझे केवल HTTP के माध्यम से फ़ाइल के पहले कुछ किलोबाइट डाउनलोड करने की आवश्यकता है।रूबी

मैं

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

की कोशिश की लेकिन यह वास्तव में पूर्ण फ़ाइल डाउनलोड करता है।

उत्तर

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 

मैं उत्सुक हूँ अगर वहाँ एक "गहरे लाल रंग का तरीका है।"

+0

हाय मिशेल, किसी कारण जब भी मैं इस तरह के 'के रूप में एक फ़ाइल की कोशिश के लिए http:// www.forcefieldpr.com/asdyoucantbealone.mp3', जो ब्राउज़र में काम करता है, मुझे 404 एचटीएमएल पेज मिल रहा है। क्या यह अनुरोध के साथ किया जाएगा? –

+0

मैंने एक संपादन सबमिट किया जो इस मुद्दे को हल करता है @AaronMoodie है। कुछ वेब सर्वरों को "होस्ट" हेडर की आवश्यकता होती है, इसलिए मैंने बस इतना जोड़ा: 'request = "GET # {path} HTTP/1.1 \ r \ n होस्ट: # {होस्ट} \ r \ n \ r \ n" ' – inket

0

"OpenURI returns two different objects" देखें। आप प्रीसेट सीमा के बाद शेष परिणाम को डाउनलोड/फेंकने में बाधा डालने के तरीकों का दुरुपयोग करने में सक्षम हो सकते हैं।

+0

दिलचस्प बात के लिए धन्यवाद – taro

3

यह एक पुराना धागा है, लेकिन यह अभी भी एक प्रश्न है जो मेरे शोध के अनुसार अधिकतर अनुत्तरित लगता है।

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 समय से पहले ही फोन: यहाँ एक समाधान बंदर-पैच Net :: HTTP थोड़ा द्वारा मैं के साथ आया है।

FYI करें, HTTPResponse वस्तु के भीतर सॉकेट एक सच्चे IO वस्तु (यह एक आंतरिक वर्ग BufferedIO कहा जाता है) नहीं है, लेकिन यह बहुत बंदर-पैच कि, भी, IO तरीकों की जरूरत है नकल करने के लिए आसान है। उदाहरण के लिए, एक और पुस्तकालय मैं (exifr) का उपयोग किया गया था readchar विधि है, जो आसान था जोड़ने के लिए की जरूरत:

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

बढ़िया! आप रास्ते से पैच किए बिना सॉकेट तक पहुंच सकते हैं, बस इसका उपयोग करें: 'response.instance_variable_get (: @ सॉकेट) .read (5120)' – inket

+0

यह समाधान ओएस एक्स 10.9 के तहत रूबी-2.0.0p247 के साथ अनिश्चित काल तक अटक गया है। समस्या को कम नहीं कर सका, लेकिन बैकट्रैक 'नेट/प्रोटोकॉल.आरबी' में लाइन 155 का उल्लेख करता है। – inket