2010-10-15 12 views
19

bir ikili dosyadan veri yorumlama:Okuma ve her byte son bit ayarlanırsa ben byte bir dosya byte okumak ve kontrol etmek istiyorum Python

#!/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() 

alıyorum hatadır:

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' 

Fikir sahibi olan var mı? Yapı ve binascii modüllerini kullanmayı başaramadım.

+2

http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly-with-integers öğeyi almadan önce * bu * çalışma * ve * bu soruyu * açın;) – delnan

cevap

7

Sen int yerine ord kullanmak istiyorum:

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

ve gerçekten Tam sayıları, kimlikleriyle değil, == 'ile karşılaştırmalı! –

+0

İyi nokta. Bunu düşündüm ama bunu yapıştırdığımda değiştirmedim ... düzeltildi. Büyük dosya çözümü için – nmichaels

36

bytearray tipini (daha sonra Python 2.6 ve üzeri), çok daha uygun bayt veri ile uğraşmaya var kullanmayı deneyin.

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

veya sonuçların listesini oluşturmak için: Sizin try blok sadece olurdu

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

Bu çalıştığı için bir bytearray sadece, oysa geri (0-255) bir tamsayı olsun Dizin Dosyadan bir bayt okursanız, tek bir karakter dizgisi alırsınız ve bu nedenle bir tamsayıya dönüştürmek için ord'u kullanmanız gerekir.


dosya (ben tahmin ediyorum gerçi değildir) daha sonra bir mmap bir tampon bytearray oluşturmak için kullanılabilecek rahatça bellekte tutmak için çok büyükse:

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

+1, saç dökülmesinden kurtuldum. Siz bir beyefendi ve bir bilginsiniz. – brichins

3

Tek yönlü:

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 

bir başka yolu:

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()