2015-04-21 12 views
8

मेरा लक्ष्य अनुरोध का उपयोग करके फ़ाइल के हिस्से का एक पुट करना है और फ़ाइल को स्ट्रीम करना है (यानी, इसे स्मृति में लोड न करें और फिर PUT करें)।अनुरोध - अपलोड कैसे करें - आंशिक फ़ाइल

This page बताते हैं आपको लगता है कि कैसे करेंगे एक पूरी फ़ाइल के लिए:

अनुरोध स्ट्रीमिंग अपलोड है, जो आप उन्हें स्मृति में पढ़ने के बिना बड़े धाराओं या फ़ाइलें भेजने के लिए अनुमति देने के समर्थन करता है। स्ट्रीम और अपलोड करने के लिए बस अपने शरीर के लिए एक फ़ाइल जैसी वस्तु प्रदान करते हैं:

with open('massive-body', 'rb') as f: 
    requests.post('http://some.url/streamed', data=f) 

हालांकि मेरे मामले में मैं केवल फ़ाइल में से एक हिस्सा भेजना चाहते हैं। क्या इसको मदद देने का कोई तरीका है?

अवधारणा में, कुछ की तरह:

with open('massive-body', 'rb') as f: 
    requests.post('http://some.url/streamed', data=f.read(chunksize)) 
+0

हम्म, आप संभवतः एक फ़ाइल-जैसी ऑब्जेक्ट होने का नाटक करने वाले जनरेटर लिख सकते हैं जो दृश्यों के पीछे एक हिस्सा पढ़ेगा, हालांकि मुश्किल हो सकता है क्योंकि मुझे यकीन नहीं है कि फाइल पर कॉल करने के अनुरोध क्या हैं, लेकिन संभव है अगर कोई भी बेहतर समाधान – user3012759

+0

@ user3012759 के साथ आता है: मैंने किसी फ़ाइल की तरह ऑब्जेक्ट में अनुरोध की आवश्यकता नहीं है, इसका कोई फायदा नहीं हुआ। हालांकि, ध्यान दें कि यह [चंक-एन्कोडेड अनुरोध] के लिए एक साधारण जनरेटर स्वीकार करता है (http://docs.python-requests.org/en/latest/user/advanced/#chunk-encoded-requests) –

+0

मुझे लगता है कि आप प्रयोग कर सकते हैं एक मूल फ़ाइल-जैसी कक्षा का उपयोग करके जिसमें 'read' और' close' विधियां हैं, और यदि यह काम नहीं करता है, तब तक आपकी कक्षा में विधियों को जोड़ना जारी रखें जब तक अनुरोध शिकायत बंद न हो जाए। :) –

उत्तर

1

मैं सिर्फ 2 अन्य उत्तर फेंक कर रहा हूँ एक साथ तो मेरे साथ सहन करता है, तो यह बॉक्स से बाहर काम नहीं करता है - मैं इस परीक्षण के कोई साधन नहीं है:

Lazy Method for Reading Big File in Python?

http://docs.python-requests.org/en/latest/user/advanced/#chunk-encoded-requests

def read_in_chunks(file_object, blocksize=1024, chunks=-1): 
    """Lazy function (generator) to read a file piece by piece. 
    Default chunk size: 1k.""" 
    while chunks: 
     data = file_object.read(blocksize) 
     if not data: 
      break 
     yield data 
     chunks -= 1 

requests.post('http://some.url/chunked', data=read_in_chunks(f)) 
+0

ध्यान दें कि ग्रेग ** ** ** पूरी फ़ाइल अपलोड नहीं करना चाहता है। हो सकता है कि आपको अपने 'chunk_size' को किसी और चीज़ में बदलना चाहिए, उदाहरण के लिए' ब्लॉकइज ', क्योंकि ग्रेग ट्रांसफर करने के लिए डेटा के कुल आकार का मतलब है' chunksize' का उपयोग कर रहा है। एफडब्ल्यूआईडब्लू, आपके कोड को लूप से तोड़ने के लिए आसानी से संशोधित किया जा सकता है जब 'चंक्साइज' बाइट्स भेजे जाते हैं, एकमात्र चाल यह है कि 'ब्लॉक%% ब्लॉक' शून्य नहीं होने पर अंतिम ब्लॉक छोटा हो सकता है। –

+0

मैंने उदाहरण अपडेट किया है ताकि आप अधिकतम संख्या – Joe

+0

ठीक निर्दिष्ट कर सकें। यह काम करता है। कॉलर को यह सुनिश्चित करना है कि 'ब्लॉकइज' 'चुनौती 'का विभाजक है, लेकिन उम्मीद है कि यह एक बड़ा मुद्दा नहीं है। –

3

ग्रेग के मेरे सवालों के जवाब बंद आधार पर मुझे लगता है कि निम्नलिखित सबसे अच्छा काम करेगा:

सबसे पहले आप कुछ की आवश्यकता होगी आपकी फ़ाइल खोलने रैप करने के लिए इतना है कि यह सीमित करता है कितना डेटा पढ़ा जा सकता है:

class FileLimiter(object): 
    def __init__(self, file_obj, read_limit): 
     self.read_limit = read_limit 
     self.amount_seen = 0 
     self.file_obj = file_obj 

     # So that requests doesn't try to chunk the upload but will instead stream it: 
     self.len = read_limit 

    def read(self, amount=-1): 
     if self.amount_seen >= self.read_limit: 
      return b'' 
     remaining_amount = self.read_limit - self.amount_seen 
     data = self.file_obj.read(min(amount, remaining_amount)) 
     self.amount_seen += len(data) 
     return data 

यह मोटे तौर पर एक अच्छी रैपर वस्तु के रूप में काम करना चाहिए। तो फिर तुम इतना है कि यह प्रयोग करेंगे:

with open('my_large_file', 'rb') as file_obj: 
    file_obj.seek(my_offset) 
    upload = FileLimiter(file_obj, my_chunk_limit) 
    r = requests.post(url, data=upload, headers={'Content-Type': 'application/octet-stream'}) 

हेडर स्पष्ट रूप से वैकल्पिक हैं, लेकिन जब एक सर्वर से डेटा स्ट्रीमिंग, यह एक अच्छा विचार एक विचारशील उपयोगकर्ता हो सकता है और सर्वर क्या वाली सामग्री के प्रकार है बताने के लिए है आप भेज रहे हैं

+1

धन्यवाद, यह वही है जो मुझे चाहिए! 'मामूली' -1 ' ' डेटा = self.file_obj.read (शेष_माउंट राशि अगर <0 और मिनट (राशि, शेष_माउंट)) के लिए 'पढ़ने' के लिए एक मामूली बग फिक्स – ryan

संबंधित मुद्दे