दिलचस्प पोस्ट
मैं एक साधारण वेब प्रोजेक्ट में एक .MDF (माइक्रोसॉफ्ट एसक्यूएल सर्वर डाटाबेस फाइल) से कैसे जुड़ूं? एक फ़ाइल "स्लिपिंग" क्यों नहीं एक अच्छा अभ्यास है? एक MySQL_query में आप एकाधिक SQL कथन कैसे करते हैं? उखाड़ने का इतिहास निकालें JSON विशेषता को निकालें क्या स्काला समर्थन पूंछ पुनर्कथन अनुकूलन करता है? ggplot: पहल लेबल बदलने के लिए कैसे? मैं अपने वेबकिट-आधारित अनुप्रयोग में स्थानीय संग्रहण कैसे सक्षम करूं? Android सूचीदृश्य के लिए कस्टम फ़ॉन्ट Matlotlib में एक्स या वाई अक्ष पर "टिक आवृत्ति" बदलना? समूहों की चर संख्या के साथ नियमित अभिव्यक्ति? मैप दृश्य में एक एनोटेशन के रूप में मैं UIPopoverView कैसे प्रदर्शित करूं? (आईपैड) एकाधिक कुंजी के द्वारा शब्दकोशों की पायथन सॉर्टिंग सूची क्या आईएमडीबी एक एपीआई प्रदान करता है? क्या जीएनयू का जावा कम्पाइलर (जीसीजे) मर चुका है?

बाइनरी फ़ाइल पढ़ना और प्रत्येक बाइट पर पाशन करना

अजगर में, मैं उस फाइल के प्रत्येक बाइट पर बाइनरी फ़ाइल और लूप में कैसे पढ़ूं?

वेब के समाधान से एकत्रित समाधान "बाइनरी फ़ाइल पढ़ना और प्रत्येक बाइट पर पाशन करना"

f = open("myfile", "rb") try: byte = f.read(1) while byte != "": # Do stuff with byte. byte = f.read(1) finally: f.close() 

चिडकी के सुझाव द्वारा:

 with open("myfile", "rb") as f: byte = f.read(1) while byte != "": # Do stuff with byte. byte = f.read(1) 

ध्यान दें कि बयान के साथ पायथन के संस्करण 2.5 में उपलब्ध नहीं है। इसे 2.5 वी में उपयोग करने के लिए आपको इसे आयात करना होगा:

 from __future__ import with_statement 

2.6 में यह आवश्यक नहीं है।

पायथन 3 में, यह थोड़ा अलग है। हम बाइट मोड में लेकिन बाइट ऑब्जेक्ट्स में धारा से कच्चे अक्षरों को नहीं प्राप्त करेंगे, इस प्रकार हमें इस शर्त को बदलना होगा:

 with open("myfile", "rb") as f: byte = f.read(1) while byte != b"": # Do stuff with byte. byte = f.read(1) 

या जैसा बेनहॉइट कहते हैं, उतना ही नहीं छोड़ें और इस तथ्य का लाभ उठाएं कि b"" झूठे के लिए मूल्यांकन करता है यह कोड 2.6 और 3.x के बीच किसी भी परिवर्तन के बिना संगत करता है। यदि आप बाइट मोड से पाठ या रिवर्स में जाते हैं तो यह आपको स्थिति बदलने से बचाएगा।

 with open("myfile", "rb") as f: byte = f.read(1) while byte: # Do stuff with byte. byte = f.read(1) 

यह जनरेटर एक फ़ाइल से बाइट्स की पैदावार करता है, फाइल को विखंडू में पढ़ना:

 def bytes_from_file(filename, chunksize=8192): with open(filename, "rb") as f: while True: chunk = f.read(chunksize) if chunk: for b in chunk: yield b else: break # example: for b in bytes_from_file('filename'): do_stuff_with(b) 

Iterators और जनरेटर पर जानकारी के लिए पायथन दस्तावेज़ीकरण देखें।

यदि फ़ाइल बहुत बड़ी नहीं है जो इसे स्मृति में रखती है तो एक समस्या है:

 bytes_read = open("filename", "rb").read() for b in bytes_read: process_byte(b) 

जहां process_byte कुछ ऑपरेशन का प्रतिनिधित्व करता है जिसे आप पारित-बाइट पर प्रदर्शन करना चाहते हैं।

यदि आप एक समय में एक हिस्सा संसाधित करना चाहते हैं:

 file = open("filename", "rb") try: bytes_read = file.read(CHUNKSIZE) while bytes_read: for b in bytes_read: process_byte(b) bytes_read = file.read(CHUNKSIZE) finally: file.close() 

फाइल पढ़ने के लिए – एक समय में एक बाइट (बफरिंग की अनदेखी) – आप दो तर्क तर्क iter(callable, sentinel) निर्मित फ़ंक्शन का उपयोग कर सकते हैं:

 with open(filename, 'rb') as file: for byte in iter(lambda: file.read(1), b''): # Do stuff with byte 

यह file.read(1) कॉल करता है। file.read(1) जब तक यह कुछ भी नहीं रिटर्न देता है b'' (रिक्त बाइट टेस्टिंग)। बड़ी फ़ाइलों के लिए स्मृति असीमित नहीं होती है आप buffering=0 को open() लिए buffering=0 पास कर सकते हैं – buffering=0 को अक्षम करने के लिए – यह गारंटी देता है कि केवल एक बाइट प्रति पुनरावृत्ति (धीमी) प्रति पढ़ा जाता है।

with फाइल स्वचालित रूप से फ़ाइल बंद कर देता है – मामले को शामिल करते समय नीचे दिए गए कोड को अपवाद को बढ़ाता है।

डिफ़ॉल्ट बफरिंग की उपस्थिति के बावजूद डिफ़ॉल्ट रूप से, यह अभी भी एक बार में एक बाइट को संसाधित करने में अक्षम है। उदाहरण के लिए, यहां blackhole.py उपयोगिता है जो यह सब कुछ खाती है:

 #!/usr/bin/env python3 """Discard all input. `cat > /dev/null` analog.""" import sys from functools import partial from collections import deque chunksize = int(sys.argv[1]) if len(sys.argv) > 1 else (1 << 15) deque(iter(partial(sys.stdin.detach().read, chunksize), b''), maxlen=0) 

उदाहरण:

 $ dd if=/dev/zero bs=1M count=1000 | python3 blackhole.py 

यह ~ 1.5 जीबी / एस की प्रक्रिया करता है, जब मेरी मशीन पर chunksize == 32768 और केवल ~ 7.5 एमबी / एस जब chunksize == 1 यही है, एक बार में एक बाइट पढ़ने के लिए 200 गुना धीमी है अगर आप एक समय में एक से अधिक बाइट का उपयोग करने के लिए अपनी प्रसंस्करण को फिर से लिख सकते हैं और आपको प्रदर्शन की आवश्यकता है, तो इसे ध्यान में रखें।

mmap आपको एक फाइल को एक bytearray और फ़ाइल ऑब्जेक्ट के रूप में एक साथ इलाज के लिए अनुमति देता है। यदि आप दोनों इंटरफेस को एक्सेस करने की आवश्यकता है तो यह पूरी फ़ाइल मेमोरी में लोड करने के विकल्प के रूप में सेवा कर सकती है विशेष रूप से, आप मेमोरी-मैप किए गए फ़ाइल पर एक समय में एक बाइट को फिर से दोहरा सकते हैं- बस के for एक सादे का उपयोग करके:

 from mmap import ACCESS_READ, mmap with open(filename, 'rb', 0) as f, mmap(f.fileno(), 0, access=ACCESS_READ) as s: for byte in s: # length is equal to the current file size # Do stuff with byte 

mmap टुकड़ा संकेतन का समर्थन करता है। उदाहरण के लिए, mm[i:i+len] स्थिति से शुरू होने वाली फाइल से len बाइट्स रिटर्न करता है i संदर्भ प्रबंधक प्रोटोकॉल Python 3.2 से पहले समर्थित नहीं है; आपको इस मामले में स्पष्ट रूप से mm.close() कॉल mm.close()file.read(1) का इस्तेमाल करते हुए प्रत्येक बाइट पर file.read(1) तुलना में अधिक मेमोरी खपत करता है। file.read(1) , लेकिन file.read(1) तीव्रता का एक क्रम है।

क्रिफी, स्कार्मेडेल, बेन होट और पीटर हैनसेन के सभी शानदार बिंदुओं को एकत्र करने के लिए, यह एक समय में बाइनरी फ़ाइल को एक बाइट प्रसंस्करण के लिए इष्टतम समाधान होगा:

 with open("myfile", "rb") as f: while True: byte = f.read(1) if not byte: break do_stuff_with(ord(byte)) 

अजगर संस्करण 2.6 और इसके बाद के संस्करण के लिए, क्योंकि:

  • अजगर बफ़र्स आंतरिक रूप से – भाग को पढ़ने की कोई ज़रूरत नहीं है
  • शुष्क सिद्धांत – रीड लाइन को दोहराएं नहीं
  • बयान के साथ एक साफ फाइल बंद सुनिश्चित करता है
  • 'बाइट' का मूल्यांकन झूठी है जब कोई और बाइट्स नहीं हैं (जब एक बाइट शून्य नहीं है)

या बेहतर गति के लिए जेएफ सेबस्टियन समाधान का उपयोग करें

 from functools import partial with open(filename, 'rb') as file: for byte in iter(partial(file.read, 1), b''): # Do stuff with byte 

या यदि आप इसे जनरेटर समारोह के रूप में चाहते हैं जैसे कोडेप द्वारा दिखाया गया है:

 def bytes_from_file(filename): with open(filename, "rb") as f: while True: byte = f.read(1) if not byte: break yield(ord(byte)) # example: for b in bytes_from_file('filename'): do_stuff_with(b) 

पायथन में बाइनरी फ़ाइल पढ़ना और प्रत्येक बाइट पर पाशन करना

ऐसा करने के लिए एक फ़ंक्शन बनाते हैं:

 def file_byte_iterator(path): """given a path, return an iterator over the file that lazily loads the file """ with open(path, 'rb') as file: for chunk in file: for byte in chunk: yield byte 

उदाहरण:

चलिए एक फाइल बनाते हैं:

 >>> path = '/temp/foobarbaz' >>> with open(path, 'w') as f: ... f.write('foo\nbar\nbaz') 

अब rb फ्लैग (रीड मोड, बाइट मोड) का उपयोग करते हुए, इसे फिर से rb

ध्यान दें कि छोरों के लिए बहुविध जटिलता (जो कि ओ (एन) को बढाता है) में वृद्धि नहीं करती है – यह वैसे ही है कि आप रेखा से लाइन-पंक्ति के आधार पर एक आज़ादी से पुन: चलाते हैं।

यह कोड में प्रत्येक बाइट पर लूप होगा, बिना किसी हैक के .read(1) व्यवसाय

 >>> for byte in file_byte_iterator(path): ... print(byte) ... #print(ord(byte)) # Python 2 102 111 111 10 98 97 114 10 98 97 122 

यह अन्य पाइप्स और जटिलता की तुलना में कहीं अधिक पायथनिक और प्राकृतिक है, जो मैंने यहां अन्य उत्तरों में देखा है।

बफ़ेड रीडिंग

अगर आपके पास कोई नई लाइनें नहीं हैं, तो आप अपना पठन बफर कर सकते हैं। पायथन 2.7 को यह प्राप्त करने के लिए io.open आवश्यकता है:

 >>> import io >>> with io.open('foobarbaz', 'rb') as f: ... for line in f: ... for byte in line: ... print(ord(byte)) 

और अब हमारे पास बफर रीडर है:

 >>> f <_io.BufferedReader name='foobarbaz'> 

पायथन 3 का निर्मित open फ़ंक्शन 2 है io.open

यदि आपके पास बहुत सारे बाइनरी डेटा पढ़ने के लिए हैं, तो आप संरचना मॉड्यूल पर विचार करना चाह सकते हैं। इसे "सी और पायथन प्रकारों के बीच" रूपांतरित करने के रूप में प्रलेखित किया गया है, लेकिन बेशक, बाइट्स बाइट्स हैं, और चाहे वे सी प्रकार के रूप में बनाए गए थे, कोई फर्क नहीं पड़ता। उदाहरण के लिए, यदि आपके बाइनरी डेटा में दो 2-बाइट पूर्णांक और एक 4-बाइट पूर्णांक है, तो आप उन्हें निम्नानुसार पढ़ सकते हैं (उदाहरण के लिए struct प्रलेखन से लिया गया है):

 >>> struct.unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03') (1, 2, 3) 

किसी फ़ाइल की सामग्री पर स्पष्ट रूप से पाशन करने के बजाय, आपको यह अधिक सुविधाजनक, तेज़ या दोनों मिल सकता है।

पायथन 3, एक बार में सभी फाइलों को पढ़िए:

 with open("filename", "rb") as binary_file: # Read the whole file at once data = binary_file.read() print(data) 

आप data वैरिएबल का उपयोग करना चाहते हैं, फिर से दोहरा सकते हैं।

मेरा समाधान वास्तव में एक स्ट्रिंग देता है:

 >>> from StringIO import StringIO >>> from functools import partial # credit to JF Sebastian >>> fl = StringIO('string\x00string2\x00') # simulated "file" object >>> bytearray(iter(partial(fl.read, 1), b'\x00')).__str__() # read until terminated 'string' >>> bytearray(iter(partial(fl.read, 1), b'\x00')).__str__() # again 'string2' 

इस के साथ एकमात्र समस्या यह है कि यदि आप एक बाहरी ऑफसेट प्रबंधित कर रहे हैं, तो आपको स्पष्ट रूप से समाप्ति वर्ण के लिए 1 जोड़ने की आवश्यकता होगी

संपादित करें:
आम तौर पर हालांकि मैं array('B',[ord(c) for c in file.read()]) करता हूँ और वहां से मैन्युअल रूप से डाटा मैनेजमेंट करता हूं।
(यह फ़ाइल डेटा को संभाल करने का सबसे तेज़ तरीका है, file.read (1) कई बार धीमा है)