दिलचस्प पोस्ट
क्वेरीस्ट्रिंग कैसे निकालें और केवल यूआरएल कैसे प्राप्त करें? क्या ट्विटर के पॉपोवर के लिए सामग्री के रूप में एक div का उपयोग संभव है? डेटा को मानकीकृत करने के लिए यह कोड कैसे काम करता है? मैं बाह्य प्रोग्राम को लिनक्स में सी कोड के अंदर तर्कों के साथ कैसे निष्पादित करता हूं? नाम डेटाबेस डिजाइन संकेतन आप पसंद करते हैं और क्यों? एक आईओएस ऐप में iMessage स्टाइल रीसिंगिंग कीबोर्ड PHP में गतिशील चर नामों के साथ ब्रेसिज़ का उपयोग करना सी ++ में प्रॉक्सी क्लास क्या है अस्थायी रूप से git से फ़ाइलें अनट्रेक करें Interlocked.CompareExchange एक स्मृति बाधा का उपयोग करता है? एकाधिक स्ट्रिंग मैचों को खोजने के लिए एल्गोरिथ्म क्या कोई सही आबादी का उपयोग करता है? PHPExcel वर्ग Zend Autoloader में नहीं मिला मैं CUDA कर्नेल के लिए ग्रिड और ब्लॉक आयाम कैसे चुनूं? एचटीएमएल फॉर्म में पट विधि का उपयोग करना

मैं HTTP पर एक बाइनरी फ़ाइल कैसे डाउनलोड करूं?

रूबी का उपयोग करते हुए मैं HTTP पर एक बाइनरी फाइल को कैसे डाउनलोड और सहेजूं?

URL http://somedomain.net/flv/sample/sample.flv

मैं विंडोज प्लेटफॉर्म पर हूं और मैं किसी बाहरी प्रोग्राम को चलाने के लिए नहीं पसंद करता।

वेब के समाधान से एकत्रित समाधान "मैं HTTP पर एक बाइनरी फ़ाइल कैसे डाउनलोड करूं?"

सरल तरीका प्लेटफ़ॉर्म-विशिष्ट समाधान है:

  #!/usr/bin/env ruby `wget http://somedomain.net/flv/sample/sample.flv` 

शायद आप इसके लिए खोज रहे हैं:

 require 'net/http' # Must be somedomain.net instead of somedomain.net/, otherwise, it will throw exception. Net::HTTP.start("somedomain.net") do |http| resp = http.get("/flv/sample/sample.flv") open("sample.flv", "wb") do |file| file.write(resp.body) end end puts "Done." 

संपादित करें: बदल दिया गया धन्यवाद।

Edit2: समाधान, जो डाउनलोड करते समय एक फ़ाइल का हिस्सा बचाता है:

 # instead of http.get f = open('sample.flv') begin http.request_get('/sample.flv') do |resp| resp.read_body do |segment| f.write(segment) end end ensure f.close() end 

मुझे पता है कि यह एक पुराना सवाल है, लेकिन Google ने मुझे यहां फेंक दिया और मुझे लगता है कि मुझे एक सरल जवाब मिला।

Railscasts # 179 में , रयान बाट्स ने रूबी मानक वर्ग ओपनुरी का इस्तेमाल किया था, जो कि इसके बारे में ज्यादा बताया गया था:

( चेतावनी : अनचेस्टर कोड। आपको इसे बदलने / बदलने की आवश्यकता हो सकती है।)

 require 'open-uri' File.open("/my/local/path/sample.flv", "wb") do |saved_file| # the following "open" is provided by open-uri open("http://somedomain.net/flv/sample/sample.flv", "rb") do |read_file| saved_file.write(read_file.read) end end 

रुबी के नेट / एचटीसी दस्तावेज में उदाहरण 3 दिखाता है कि HTTP पर एक दस्तावेज़ कैसे डाउनलोड किया जाए और फ़ाइल को मेमोरी में लोड करने के बजाय फ़ाइल को आउटपुट करने के लिए, फाइल में द्विआधारी लिखने के लिए विकल्प डालता है, जैसे कि डीजेड के उत्तर में दिखाया गया है।

अधिक जटिल मामलों को एक ही दस्तावेज में और नीचे दिखाया गया है।

आप ओपन-यूरी का उपयोग कर सकते हैं, जो एक लाइनर है

 require 'open-uri' content = open('http://example.com').read 

या नेट / http का उपयोग करके

 require 'net/http' File.write("file_name", Net::HTTP.get(URI.parse("http://url.com"))) 

IO::copy_stream(src, dst) का उपयोग कर फाइल करने के लिए मेरा रुबी http है IO::copy_stream(src, dst)

 require "open-uri" def download(url, path) File.open(path, "w") do |f| IO.copy_stream(open(url), f) end end 

इसका मुख्य लाभ यह है कि यह पढ़ता है और विखंडू में लिखता है, और इस तरह स्मृति में पूरी प्रतिक्रिया नहीं पढ़ता है।

इस प्रदर्शन के उद्देश्य के लिए मैं open(name, *rest, &block) उपयोग करता हूं। IO::copy_stream(src, dst) का पहला तर्क किसी भी आईओ ऑब्जेक्ट हो सकता है जो पढ़ने के लिए प्रतिक्रिया करता है।

कृपया उपयोगकर्ता द्वारा उपलब्ध इनपुट के साथ सावधान रहें! अगर उपयोगकर्ता इनपुट से name आ रहा है तो open(name, *rest, &block) असुरक्षित है!

डीजे के उत्तर पर विस्तार (संपादित करें 2):

 File.open(filename,'w'){ |f| uri = URI.parse(url) Net::HTTP.start(uri.host,uri.port){ |http| http.request_get(uri.path){ |res| res.read_body{ |seg| f << seg #hack -- adjust to suit: sleep 0.005 } } } } 

जहां filename और url तार हैं

sleep कमांड एक हैक जो नाटकीय ढंग से CPU उपयोग को कम कर सकता है जब नेटवर्क सीमित कारक है। नेट :: HTTP बफर के लिए इंतजार नहीं करता (बफर में 16kB) v1.9.2 उपज से पहले भरने के लिए, इसलिए सीपीयू busies खुद चारों ओर छोटे विखंडन चलती। एक पल के लिए सो रही बफर को लिखने के बीच भरने का मौका मिलता है, और CPU उपयोग एक कर्ल समाधान के बराबर है, मेरे आवेदन में 4-5x अंतर। एक अधिक मजबूत समाधान f.pos की प्रगति की जांच कर सकता है और बफर आकार के 95% लक्ष्य को लक्षित करने के लिए समय समाप्ति को समायोजित कर सकता है – वास्तव में यह है कि मुझे अपने उदाहरण में 0.005 संख्या मिली है।

क्षमा करें, लेकिन मैं रूबी को भरने के लिए रूबी की प्रतीक्षा करने का एक और शानदार तरीका नहीं जानता।

संपादित करें:

यह एक ऐसा संस्करण है जो स्वचालित रूप से बफर को क्षमता पर या नीचे रखने के लिए खुद को समायोजित कर देता है यह एक असहनीय समाधान है, लेकिन ऐसा लगता है कि यह तेज़ है, और सीपीयू के छोटे-छोटे समय के रूप में उपयोग करने के लिए, क्योंकि यह कर्ल के लिए बुला रहा है

यह तीन चरणों में काम करता है एक जानबूझकर लंबी नींद के साथ एक संक्षिप्त सीखने की अवधि एक पूर्ण बफर के आकार को स्थापित करता है बूंद की अवधि प्रत्येक चलना के साथ जल्दी से नींद के समय को कम कर देता है, जब तक कि इसे एक भरे बफर नहीं मिल जाता है। फिर, सामान्य अवधि के दौरान, यह एक छोटी कारक द्वारा ऊपर और नीचे समायोजित करता है

मेरा रूबी थोड़ी सी जंगली है, इसलिए मुझे यकीन है कि इस पर सुधार किया जा सकता है। सबसे पहले, कोई त्रुटि हैंडलिंग नहीं है। इसके अलावा, शायद यह किसी ऑब्जेक्ट में अलग हो सकता है, डाउनलोड करने से ही दूर हो सकता है, ताकि आप अपने लूप में बस autosleep.sleep(f.pos) को कॉल कर autosleep.sleep(f.pos) ? इससे भी बेहतर, नेट :: HTTP उपज देने से पहले एक पूर्ण बफर के लिए प्रतीक्षा करने के लिए बदला जा सकता है 🙂

 def http_to_file(filename,url,opt={}) opt = { :init_pause => 0.1, #start by waiting this long each time # it's deliberately long so we can see # what a full buffer looks like :learn_period => 0.3, #keep the initial pause for at least this many seconds :drop => 1.5, #fast reducing factor to find roughly optimized pause time :adjust => 1.05 #during the normal period, adjust up or down by this factor }.merge(opt) pause = opt[:init_pause] learn = 1 + (opt[:learn_period]/pause).to_i drop_period = true delta = 0 max_delta = 0 last_pos = 0 File.open(filename,'w'){ |f| uri = URI.parse(url) Net::HTTP.start(uri.host,uri.port){ |http| http.request_get(uri.path){ |res| res.read_body{ |seg| f << seg delta = f.pos - last_pos last_pos += delta if delta > max_delta then max_delta = delta end if learn <= 0 then learn -= 1 elsif delta == max_delta then if drop_period then pause /= opt[:drop_factor] else pause /= opt[:adjust] end elsif delta < max_delta then drop_period = false pause *= opt[:adjust] end sleep(pause) } } } } end 

उदाहरण के लिए, Net::HTTP से अधिक एपी-फ्रेंडली लाइब्रेरी है http :

 require "httparty" File.open("/tmp/my_file.flv", "wb") do |f| f.write HTTParty.get("http://somedomain.net/flv/sample/sample.flv").parsed_response end 

मुझे समस्याएं थी, अगर फ़ाइल में जर्मन यूमेलओट्स (ए, ओ, यू) शामिल हैं। मैं इस समस्या का समाधान कर सकता हूं:

 ec = Encoding::Converter.new('iso-8859-1', 'utf-8') ... f << ec.convert(seg) ... 

अगर आप अस्थायी फ़ाइल को डाउनलोड करने, सामान करते हैं और इसे हटाने के लिए इस मणि की कोशिश करते हैं तो https://github.com/equivalent/pull_tempfile

 require 'pull_tempfile' PullTempfile.transaction(url: 'https://mycompany.org/stupid-csv-report.csv', original_filename: 'dont-care.csv') do |tmp_file| CSV.foreach(tmp_file.path) do |row| # .... end end