2010-10-15 15 views
19

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

#!/usr/bin/python 

def main(): 
    fh = open('/tmp/test.txt', 'rb') 
    try: 
     byte = fh.read(1) 
     while byte != "": 
      if (int(byte,16) & 0x01) is 0x01: 
       print 1 
      else: 
       print 0 
      byte = fh.read(1) 
    finally: 
     fh.close 

    fh.close() 

if __name__ == "__main__": 
     main() 

त्रुटि मैं मिलता है:

Traceback (most recent call last): 
    File "./mini_01.py", line 21, in <module> 
    main() 
    File "./mini_01.py", line 10, in main 
    if (int(byte,16) & 0x01) is 0x01: 
ValueError: invalid literal for int() with base 16: '\xaf' 

कोई भी विचार है? मैं संरचना और binascii मॉड्यूल का उपयोग करने में सफल नहीं हुआ।

+2

http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly-with-integers * यह * काम करने से पहले * उस * काम * के एक डुप्ले को खोलने और खोलने से पहले पढ़ें; – delnan

उत्तर

7

आप int के बजाय ord उपयोग करना चाहते हैं:

if (ord(byte) & 0x01) == 0x01: 
+5

और आप वास्तव में '==' के साथ पूर्णांक की तुलना करना चाहिए, उनकी पहचान से नहीं! –

+0

अच्छा बिंदु। मैंने इसके बारे में सोचा, लेकिन जब मैंने चिपकाया तो इसे बदल नहीं दिया ... तय। बड़े फ़ाइल समाधान के लिए – nmichaels

36

bytearray प्रकार (अजगर 2.6 और बाद में), यह काफी बेहतर बाइट डाटा के साथ काम के लिए उपयुक्त है का उपयोग करें। आपका try ब्लॉक सिर्फ होगा:

ba = bytearray(fh.read()) 
for byte in ba: 
    print byte & 1 

या परिणामों की एक सूची बनाने के लिए:

low_bit_list = [byte & 1 for byte in bytearray(fh.read())] 

यह काम करता है, क्योंकि जब आप सूचकांक एक bytearray तुम सिर्फ वापस एक पूर्णांक प्राप्त (0-255), जबकि अगर आप फ़ाइल से एक बाइट पढ़ते हैं तो आपको एक सिंगल कैरेक्टर स्ट्रिंग वापस मिलती है और इसलिए इसे ord का उपयोग करने के लिए इसे पूर्णांक में बदलने की आवश्यकता होती है।


यदि आपकी फ़ाइल आराम से स्मृति में धारण करने के लिए बहुत बड़ी है (हालांकि मैं यह अनुमान लगा रहा हूँ नहीं है) तो एक mmap एक बफर से bytearray बनाने के लिए इस्तेमाल किया जा सकता है:

import mmap 
m = mmap.mmap(fh.fileno(), 0, access=mmap.ACCESS_READ) 
ba = bytearray(m) 
+2

+1, मुझे बहुत बाल-फाड़ने से बचाया गया था। आप, श्रीमान, सज्जन और विद्वान हैं। – brichins

3

एक ही रास्ता:

import array 

filebytes= array.array('B') 
filebytes.fromfile(open("/tmp/test.txt", "rb")) 
if all(i & 1 for i in filebytes): 
    # all file bytes are odd 

एक और तरीका है:

fobj= open("/tmp/test.txt", "rb") 

try: 
    import functools 
except ImportError: 
    bytereader= lambda: fobj.read(1) 
else: 
    bytereader= functools.partial(fobj.read, 1) 

if all(ord(byte) & 1 for byte in iter(bytereader, '')): 
    # all bytes are odd 
fobj.close() 
संबंधित मुद्दे